C# 奇数泛型约束问题
为什么这个不行C# 奇数泛型约束问题,c#,generics,C#,Generics,为什么这个不行 public interface IBus { void Subscribe<T>(ISubscribe<T> subscriber) where T : class, IEvent; void Send<T>(IEvent @event) where T : class, IEvent; } class InMemoryEventBus : IBus {
public interface IBus
{
void Subscribe<T>(ISubscribe<T> subscriber) where T : class, IEvent;
void Send<T>(IEvent @event) where T : class, IEvent;
}
class InMemoryEventBus : IBus
{
private readonly IDictionary<ISubscribe<IEvent>, Type> _subscribers;
public InMemoryEventBus()
{
_subscribers= new Dictionary<ISubscribe<IEvent>, Type>();
}
public void Subscribe<T>(ISubscribe<T> subscriber) where T : class, IEvent
{
_subscribers.Add(subscriber, typeof(T));
}
public void Send<T>(IEvent @event) where T : class, IEvent
{
foreach (var subscriber in _subscribers.Where(subscriber => subscriber.Value == typeof(T)))
{
subscriber.Key.Handle(@event);
}
}
}
public interface IEvent
{
Guid EventId { get; set; }
}
public interface ISubscribe<T> where T : IEvent
{
void Handle(T @event);
}
public class StockLevelDroppedBellowMinimumLevelEvent : IEvent
{
public Guid EventId { get; set; }
public string Message { get; set; }
}
公共接口IBus
{
无效订阅(ISubscribe subscriber),其中T:class,IEvent;
void Send(IEvent@event),其中T:class,IEvent;
}
MemoryEventBus中的类:IBus
{
专用只读IDictionary用户;
公共InMemoryEventBus()
{
_订阅者=新字典();
}
公共无效订阅(ISubscribe subscriber),其中T:class,IEvent
{
_订户。添加(订户,类型(T));
}
公共无效发送(IEvent@event),其中T:class,IEvent
{
foreach(var subscriber in_subscribers.Where(subscriber=>subscriber.Value==typeof(T)))
{
subscriber.Key.Handle(@event);
}
}
}
公共接口事件
{
Guid EventId{get;set;}
}
公共接口是订阅的,其中T:IEvent
{
无效句柄(T@事件);
}
公共类StockLevelDroppedBellowMinimumLevelEvent:IEEvent
{
公共Guid事件ID{get;set;}
公共字符串消息{get;set;}
}
我得到:
cannot convert from 'IHandle<T>' to 'IHandle<IEvent>'
无法从“IHandle”转换为“IHandle”
编辑:实际上是issubscribe
需要协变-但是现在我们可以看到issubscribe
的声明,你不能使它协变-只有逆变
一般来说,类型不是泛型变体。例如,一个ICollection
不是一个ICollection
——这是一个好工作,否则这将编译:
ICollection<string> strings = new List<string>();
ICollection<object> objects = strings; // Fortunately this isn't valid
objects.Add(new Button()); // This should be fine of course...
string x = strings[0]; // But what would this do?!
编辑:它实际上是
issubscribe
,需要是协变的-但是现在我们可以看到issubscribe
的声明,你不能使它协变-只有逆变
一般来说,类型不是泛型变体。例如,一个ICollection
不是一个ICollection
——这是一个好工作,否则这将编译:
ICollection<string> strings = new List<string>();
ICollection<object> objects = strings; // Fortunately this isn't valid
objects.Add(new Button()); // This should be fine of course...
string x = strings[0]; // But what would this do?!
如果我将协变项添加到IEVent中,它将成为任何指针?@Iwayno:抱歉,它是
ISubscribe
,需要协变项编辑。但是,我得到了无效的方差:类型参数“T”必须是反变项valid@iwayneo:现在看一看。你应该可以直接把我的类放进去——已经修复了你接口名的输入错误(issubscribe->issubscribe)@iwayno:是的,你的接口根本不能是协变的;在看到它之前我不可能告诉你。但是ISubscribe
在逻辑上不是ISubscribe
——我不能让它处理任何IEvent
,可以吗?只有正确类型的事件。如果我将协变项添加到IEVent,它将成为任何指针?@Iwayno:抱歉,它是ISubscribe
,需要协变项-编辑。但是,我得到的协变项无效:类型参数“T”必须是反变项valid@iwayneo:现在看一看。你应该可以直接把我的类放进去——已经修复了你接口名的输入错误(issubscribe->issubscribe)@iwayno:是的,你的接口根本不能是协变的;在看到它之前我不可能告诉你。但是ISubscribe
在逻辑上不是ISubscribe
——我不能让它处理任何IEvent
,可以吗?只有正确的事件。