Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.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_Interface - Fatal编程技术网

C#将派生泛型类型添加到字典或列表

C#将派生泛型类型添加到字典或列表,c#,generics,interface,C#,Generics,Interface,当我在C#中尝试以下操作时,我得到一个NPE。这可能不是应该如何工作的: private readonly Dictionary<Type, List<Subscription<Event>>> subscriptionMap = new Dictionary<Type, List<Subscription<Event>>>();; public void Subscribe<T>(Action<T>

当我在C#中尝试以下操作时,我得到一个NPE。这可能不是应该如何工作的:

private readonly Dictionary<Type, List<Subscription<Event>>> subscriptionMap = new Dictionary<Type, List<Subscription<Event>>>();;

public void Subscribe<T>(Action<T> action) where T : Event {
  ...

  subscriptionMap[type].Add(new DefaultSubscription<T>(action) as Subscription<Event>);

  ...
}
private readonly Dictionary subscriptionMap=new Dictionary();;
公共无效订阅(操作操作),其中T:Event{
...
subscriptionMap[type]。添加(新的默认订阅(操作)作为订阅);
...
}
如果没有
as
的话,我会得到编译器错误,它只会在列表中添加一个空值。我应该注意到
Subscription
Event
都是接口。在Java中,我会简单地说
,这将不会产生任何问题


在此问题上的任何帮助都将不胜感激

一般委托不保证签名匹配

如果
Subscribe(Action)
使用具体的实现调用
操作
,会发生什么

Subscribe((具体事件e)=>{});
...
私有无效订阅(操作)
其中T:事件
{
操作(新事件());//与方法签名不匹配
subscriptionMap[type]。添加(新的默认订阅(操作)作为订阅);
}
这将导致编译器错误

无论方法签名需要一个具体的子类型,还是
事件
基类型,我们都不能说。我们唯一可以肯定的是,该方法采用了一个实现
事件的参数

因此,我们需要更改
Subscribe
方法,以便知道
Action
的签名。由于
Action
委托是,这意味着您可以将
T
的任何子类型传递到Action中,因此我们可以将签名更改为
Action

公共作废订阅(操作)
{
subscriptionMap[type].Add(新建DefaultSubscription(操作));
}

一般委托不保证签名匹配

如果
Subscribe(Action)
使用具体的实现调用
操作
,会发生什么

Subscribe((具体事件e)=>{});
...
私有无效订阅(操作)
其中T:事件
{
操作(新事件());//与方法签名不匹配
subscriptionMap[type]。添加(新的默认订阅(操作)作为订阅);
}
这将导致编译器错误

无论方法签名需要一个具体的子类型,还是
事件
基类型,我们都不能说。我们唯一可以肯定的是,该方法采用了一个实现
事件的参数

因此,我们需要更改
Subscribe
方法,以便知道
Action
的签名。由于
Action
委托是,这意味着您可以将
T
的任何子类型传递到Action中,因此我们可以将签名更改为
Action

公共作废订阅(操作)
{
subscriptionMap[type].Add(新建DefaultSubscription(操作));
}

什么是
DefaultSubscription
以及它与
Subscription
的关系如何?它正在实现
Subscription
请注意,仅仅因为两种类型显示特定的继承/实现关系,并不意味着由这些类型指定的泛型参数显示相同的关系。您看到的空值正是因为无法将实例转换为“基”键入。在这种情况下,我应该如何基于基本界面创建一个通用列表来存储订阅组合?即使我在没有模板的情况下使
订阅
具体化,我对
操作
也有同样的问题,我无法将其传递到
订阅
,因为我无法将其强制转换为
操作
出于什么原因。什么是
默认订阅
以及它与
订阅
的关系如何?它正在实现
订阅
请注意,仅仅因为这两种类型表现出特定的继承/实现关系,这并不意味着由这些类型参数化的泛型表现出相同的关系。您看到的空值正是因为无法将实例转换为“基”键入。在这种情况下,我应该如何基于基本界面创建一个通用列表来存储订阅组合?即使我在没有模板的情况下使
订阅
具体化,我对
操作
也有同样的问题,我无法将其传递到
订阅
,因为我无法将其强制转换为
行动
出于什么原因。@Dharman感谢您指出这一点。“我已经改变了我的答案。”达曼,谢谢你指出这一点。我已经改变了我的答案。