otrzymuje następujące interfejs:zbiór różnych typów generycznych
public interface IEventHandler<in TEvent> where TEvent : IEvent
{
void Process(TEvent @event);
}
Jakiego typu IEnumerable można używać do przechowywania kolekcji IEventHandler<TEvent>
wdrożeń gdzie TEvent jest inaczej?
tj Biorąc pod uwagę następujące 3 implementacje:
public class BlahEvent1EventHandler : IEventHandler<Event1>
{
...
}
public class WhateverEvent1EventHandler : IEventHandler<Event1>
{
...
}
public class BlahEvent2EventHandler : IEventHandler<Event2>
{
...
}
mogę zrobić nic lepszego niż zbiór obiektów?
var handlers = new List<object>
{
new BlahEvent1EventHandler(),
new WhateverEvent1EventHandler(),
new BlahEvent2EventHandler(),
};
BTW, widziałem kilka innych odpowiedzi propagującej korzystanie z typu podstawowego lub odziedziczonego interfejsu non-rodzajowego, ale nie może zobaczyć, jak to będzie dodać ogromną ilość wartości w tym przypadku chyba że ja czegoś brakuje. Tak, pozwoliłoby mi to dodać je wszystkie do kolekcji w nieco bezpieczniejszy sposób niż przy użyciu obiektu, ale nie pozwoliłoby mi na ich powtórzenie i wywołanie mocno napisanej metody procesu bez rzutowania, tak jak potrzebuję zrobić z obiektem.
public interface IEventHandler
{
}
public interface IEventHandler<in TEvent> : IEventHandler where TEvent : IEvent
{
void Process(TEvent @event);
}
nadal muszę rzucać jeśli mam IEnumerable<IEventHandler>
lub IEnumerable<obect>
foreach (var handler in _handlers.Cast<IEventHandler<TEvent>>())
{
handler.Process(@event);
}
wszelkie myśli o tym, jak poprawić?
Nie sądzę, nie ma na odwrót. Chętnie posłuchałbym interesujących informacji na ten temat, ponieważ prawie codziennie gram w tym samym numerze. –
Protip: nie nazwij zmiennych tak jak słowa kluczowe w języku. – tomfanning
Ponieważ elementy różnych typów na liście wymagałyby wywoływania różnych metod "Procesowych" z różnymi typami argumentów, jak byś je nazwał? Zauważ, że w tym przypadku nie wystąpiłaby żadna metoda zabezpieczenia przed przeciążeniem, ponieważ typ elementu listy jest znany tylko w środowisku wykonawczym. Celem generycznych jest dostarczenie statycznego typu znanego w czasie kompilacji. –