I'm trying to understand how Variance works. I have created a IRegistry interface which supports a Contravarint TDomainEvent and a Contravariant TDomainContraVariant. The thing is that the TDomainEvent extends a IDomainEvent and the TDomainContraVariant extends an IDomainEventHandler<TDomainEvent>.
For some reason I get errors saying that it is not possible to convert TDomainContraVariant to IDomainEventHandler<IDomainEvent>, which should be possible as a TDomainEvent extends an IDomainEvent.
using System;
using System.Collections.Generic;
public interface IDomainEvent {}
public class ProductSetCreatedEvent : IDomainEvent {}
public class VersionCreatedEvent : IDomainEvent {}
public class ProductSetCreatedEventHandler : IDomainEventHandler<ProductSetCreatedEvent> {}
public class VersionCreatedEventHandler : IDomainEventHandler<VersionCreatedEvent> {}
public interface IDomainEventHandler<in TDomainEvent> where TDomainEvent : IDomainEvent {}
public interface IRegistry<in TDomainEvent, in TDomainContraVariant>
where TDomainEvent : IDomainEvent
where TDomainContraVariant : IDomainEventHandler<TDomainEvent>
{
void Add(TDomainContraVariant element);
}
public class Registry<TDomainEvent, TDomainContraVariant> : IRegistry<TDomainEvent, TDomainContraVariant>
where TDomainEvent : IDomainEvent
where TDomainContraVariant : IDomainEventHandler<TDomainEvent>
{
private IList<IDomainEventHandler<IDomainEvent>> list;
public Registry()
{
this.list = new List<IDomainEventHandler<IDomainEvent>>();
}
public void Add(TDomainContraVariant element)
{
this.list.Add(element);
}
public IList<IDomainEventHandler<IDomainEvent>> Get()
{
return this.list;
}
}
public class Program
{
private static Registry<IDomainEvent, IDomainEventHandler<IDomainEvent>> list = new Registry<IDomainEvent, IDomainEventHandler<IDomainEvent>>();
public static void Main()
{
IDomainEventHandler<ProductSetCreatedEvent> eventHandler = new ProductSetCreatedEventHandler();
AddToRegistry<ProductSetCreatedEvent, IDomainEventHandler<ProductSetCreatedEvent>>(eventHandler);
}
public static void AddToRegistry<TDomainEvent, TDomainContraVariant>(TDomainContraVariant cesto)
where TDomainEvent : IDomainEvent
where TDomainContraVariant : IDomainEventHandler<TDomainEvent>
{
list.Add(cesto);
}
}