Ho la seguente interfaccia:Impossibile convertire tipo concreto alla versione generica della sua interfaccia in C#
public interface INotificationHandler<T>
{
Task<T> Handle(string msg);
}
E diverse classi che felicemente implementare in questo modo:
public class FooHandler : INotificationHandler<Foo>
{
public Task<Foo> Handle(string msg) { return Task.FromResult<Foo>(new Foo()); }
}
public class BarHandler : INotificationHandler<Bar>
{
public Task<Bar> Handle(string msg) { return Task.FromResult<Bar>(new Bar()); }
}
mi piacerebbe come mantenere una raccolta di istanze di INotificationHandler in una raccolta e quando ricevo un messaggio "foo", usa FooHandler, "bar" ottiene BarHandler, ecc ...
var notificationHandlers = new Dictionary<string, INotificationHandler<object>>();
notificationHandlers["foo"] = new FooHandler();
notificationHandlers["bar"] = new BarHandler();
...
public void MessageReceived(string type, string msg)
{
INotificationHandler<object> handler = notificationHandlers[type];
handler.Notify(msg).ContinueWith((result) => /* do stuff with a plain object */)
}
Tuttavia questo non riesce a compilare perché il mio generico non ha un tipo di base comune, che è di progettazione. Qualsiasi oggetto dovrebbe essere in grado di essere restituito da un INotificationHandler in MessageReceived
.
Impossibile convertire implicitamente il tipo
FooHandler
inINotificationHandler<object>
. Esiste Una conversione esplicita (che le manca un cast?)
Come posso lavorare con INotificationHandler<T>
in modo che non ho bisogno di cure circa i tipi generici di sue implementazioni concrete?
Hai provato a dichiarare l'interfaccia pubblica INotificationHandler? –
Secondo me questo sconfigge completamente lo scopo dei generici. – juharr
@JerryFederspiel L'ho provato, tuttavia T deve essere invariabilmente valido? Scostamento non valido: il parametro tipo "T" deve essere invarialmente valido su "INotificationHandler. Handle (stringa)". 'T' è covariante. –
plemarquand