Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 奇数泛型约束问题_C#_Generics - Fatal编程技术网

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
,可以吗?只有正确的事件。