如何在C#中的类型安全集合中存储具有约束泛型类型的Action代理? [英] How to store Action delegates with constrained generic type in a type safe collection in C#?
问题描述
假设我想将代理存储在这样的集合中:
public void AddDelegate< T> ; action)where T:ISomething
{
_delegates.Add(action);
}
什么类型的 _delegates
be?
尝试使用 IList< Action< ISomething>> _delegates;
导致错误消息 参数类型'System.Action< T>'不能分配给参数类型System.Action< ISomething>
为上述添加
调用。但为什么它不起作用?编译器应该知道T必须是 ISomething
。
如果我不想通过使用例如,不想放松类型安全,我有什么选择一个 IList< object>
或参数化泛型类型 T
?
_delegates
必须是类型 IList< Action< T>
。
因此,您必须添加< T>其中T:ISomething
到类。
或者,不要使用泛型和支持 Action< ISomething> / code>直接。
所以你的两个选项是:
public class Delegates< T>其中T:ISomething
{
private List< Action< T>> _delegates;
public void AddDelegate(Action< T> action)
{
_delegates.Add(action);
}
}
或
public class Delegates
{
private List< Action< ISomething>> _delegates;
public void AddDelegate(Action< ISomething> action)
{
_delegates.Add(action);
}
}
修改
正如Sehnsucht指出的,还有第三个选项:将 Action< T>
委托在一个 Action< ISomething>
委托中,然后OP可以实现他原本想要的。
原因是,虽然 Let's say I want to store delegates in a collection like this: What should the type of Trying with Therefore you have to add the Alternatively, do away with the generics and support So your two options are: Or Edit
As Sehnsucht points out, there's a third option: wrap the The reason for this is that whilst 这篇关于如何在C#中的类型安全集合中存储具有约束泛型类型的Action代理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! T
是 ISomething
的子类型(实现者), Action< T>
不是 Action< ISomething>
的子类型,实际上正如dcastro在他的回答中所解释的那样,实际上是相反的(尽管看起来是直觉的)。即使使用转换,也不能将 Action< T>
的实例添加到 Action< ISomething>
列表中。 / p> public void AddDelegate<T>(Action<T> action) where T : ISomething
{
_delegates.Add(action);
}
_delegates
be?IList<Action<ISomething>> _delegates;
results in error message Argument type 'System.Action<T>' is not assignable to parameter type 'System.Action<ISomething>'
for the Add
call above. But why doesn't it work? The compiler should 'know' that T must be an ISomething
.
What are my options if I don't want to loose type safety by using e.g. a IList<object>
or parameterize the whole class on the generic type T
?_delegates
has to be of type IList<Action<T>>
. <T> where T : ISomething
to the class.Action<ISomething>
directly.public class Delegates<T> where T : ISomething
{
private List<Action<T>> _delegates;
public void AddDelegate(Action<T> action)
{
_delegates.Add(action);
}
}
public class Delegates
{
private List<Action<ISomething>> _delegates;
public void AddDelegate(Action<ISomething> action)
{
_delegates.Add(action);
}
}
Action<T>
delegate inside an Action<ISomething>
delegate and then the OP can achieve what he originally wanted.T
is a "subtype" (implementer) of ISomething
, Action<T>
is not a subtype of Action<ISomething>
, in fact as dcastro explains in his answer, the opposite is actually true (despite that seeming counter-intuitive). Even with casting, you cannot add an instance of Action<T>
to a list of Action<ISomething>
.