Итак, я прочитал несколько вещей о ковариации и контравариантности в C# и подумал, что понял это, но этот код не работает, и я не уверен, почему.
public class EventService
{
private readonly Dictionary<Type, ImmutableList<Func<DomainEvent, Task>>> _listeners
= new Dictionary<Type, ImmutableList<Func<DomainEvent, Task>>>();
public async Task Fire(DomainEvent domainEvent)
{
var listeners = _listeners.GetValueOrDefault(domainEvent.GetType(),
ImmutableList<Func<DomainEvent, Task>>.Empty);
foreach (var listener in listeners!)
{
await listener.Invoke(domainEvent);
}
}
public void AddListener<T>(Func<T, Task> func) where T: DomainEvent
{
var listeners = _listeners.GetValueOrDefault(typeof(T),
ImmutableList<Func<DomainEvent, Task>>.Empty);
_listeners[typeof(T)] = listeners.Add(func); // This line fails with:
// 'Argument type 'System.Func<T,System.Threading.Tasks.Task>' is
// not assignable to parameter type
// 'System.Func<Domain.Core.DomainEvent,System.Threading.Tasks.Task>'
}
}
public abstract class DomainEvent
{
}
Я думал, что where T: DomainEvent
позволил бы ему работать, так как все - доменные события, но это не понравилось. До сих пор я не смог понять, что я сделал неправильно, и где было мое недоразумение.