Обобщенные интерфейсы в Delphi | Participants
|
- Statistics
- Participants
- Translate into Russian
- Translation result
- Translation complete.
If you do not want to register an account, you can sign in with OpenID.
Generic Interfaces in Delphi | ||
Most of the examples I’ve seen of Generics in Delphi use classes containing a generic type. However, while working on a personal project, I decided I wanted an Interface containing a generic type. | Большинство примеров использования дженериков в Delphi используют класс с дженерик-типом. Однако, работая над своим проектом, я решил, что мне нужен интерфейс с дженерик-типом. | |
The project uses an in-process publish/subscribe mechanism, and I wanted a subscriber to have a separate Receive method for each event type, rather than a single method which contained a big case statement with branches for each event type. Equally, however, I didn’t want to have to define an interface type for each event type. What I wanted was to have a generic Subscriber interface, that took the event type as a parameter. | В проекте используется встроенный механизм издатель-подписчик. Я захотел чтобы подписчик имел для каждого типа события отдельный метод Receive, а не отдельный метод с огромным case-выражением, выбирающим действие для каждого типа события. Также я не хотел определять интерфейс для каждого типа события. Мне был нужен дженерик интерфейс подписчика, который получает тип события, как параметр. | |
However, I had no idea if I could define a generic Interface, let alone implement one. Even assuming I could do both of those things, would Delphi be able to resolve the correct Receive method to invoke? Only one way to find out…. | Однако, я понятия не имел, могу ли я определить дженерик интерфейс, не говоря уже о реализации. Даже если предположить, что я могу сделать это, сможет ли Delphi выбрать правильный метод Receive для вызова? Есть только один способ узнать ... | |
NB: In this example, I’ve stripped out most of the pub/sub stuff, just leaving the pieces needed to show the generic interfaces. I’ll write about the other pieces over the next few posts. | Обратите внимание: в этом примере убраны некоторые части кода, оставлены лишь те части, которые необходимы для демонстрации дженерик интерфейсов. О других частях я расскажу в своих следующих сообщениях. | |
First, I implemented a few sample events. The contents of these are not that interesting: | Сперва я описал несколько простых событий. Их содержание не так интересно: | |
TSomeEvent = class | ||
// other stuff | ||
end; | ||
TSomeOtherEvent = class | ||
// other stuff | ||
end; | ||
Then, I defined a generic interface | ||
ISubscriber<T> = interface | ||
procedure Receive(Event : T); | ||
end; | ||
This is the interface that will need to be implemented by my subscribers in order to receive events of a particular type. Note, the type of event is set up as a generic type T. | Этот интерфейс должен быть реализован подписчиками для получения событий разного типа. Заметьте, тип событий записан как джененрик тип <T>. | |
Then, my subscribers need to implement an interface for each Event type they want to receive, however because it is a generic interface, it’s pretty straight-forward: | Затем, подписчики должны реализовать интерфейс для каждого типа событий, которые они хотят принимать. Поскольку это дженерик интерфейс - это довольно просто: | |
TMySubscribingObject = class(TInterfacedObject, ISubscriber<TSomeEvent>, ISubscriber<TSomeOtherEvent>) | TMySubscribingObject = class(TInterfacedObject, ISubscriber<TSomeEvent>, ISubscriber<TSomeOtherEvent>) | |
protected | ||
procedure Receive(Event : TSomeEvent); overload; | ||
procedure Receive(Event : TSomeOtherEvent); overload; | procedure Receive(Event : TSomeOtherEvent); overload; | |
end; | ||
Note there’s no definition of a ISomeEventSubscriber and a ISomeOtherEventSubscriber interface, we can just use ISubscriber<T> and pass the type in in-place. We just need to implement the necessary overloaded Receive events. | Здесь нет описания интерфейсов ISomeEventSubscriber и ISomeOtherEventSubscriber, мы можем просто использовать ISubscriber<T> и передать тип на месте. Для этого нужно реализовать обязательно перегруженный метод Receive. |
