如何在C#中的类型安全集合中存储具有约束泛型类型的Action代理? [英] How to store Action delegates with constrained generic type in a type safe collection in C#?

查看:132
本文介绍了如何在C#中的类型安全集合中存储具有约束泛型类型的Action代理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我想将代理存储在这样的集合中:

  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可以实现他原本想要的。



原因是,虽然 T ISomething 的子类型(实现者), Action< T> 不是 Action< ISomething> 的子类型,实际上正如dcastro在他的回答中所解释的那样,实际上是相反的(尽管看起来是直觉的)。即使使用转换,也不能将 Action< T> 的实例添加到 Action< ISomething> 列表中。 / p>

Let's say I want to store delegates in a collection like this:

public void AddDelegate<T>(Action<T> action) where T : ISomething
{
   _delegates.Add(action);
}

What should the type of _delegates be?

Trying with 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>>.

Therefore you have to add the <T> where T : ISomething to the class.

Alternatively, do away with the generics and support Action<ISomething> directly.

So your two options are:

public class Delegates<T> where T : ISomething
{
    private List<Action<T>> _delegates;

    public void AddDelegate(Action<T> action)
    {
        _delegates.Add(action);
    }
}

Or

public class Delegates
{
    private List<Action<ISomething>> _delegates;

    public void AddDelegate(Action<ISomething> action)
    {
        _delegates.Add(action);
    }
}

Edit As Sehnsucht points out, there's a third option: wrap the Action<T> delegate inside an Action<ISomething> delegate and then the OP can achieve what he originally wanted.

The reason for this is that whilst 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>.

这篇关于如何在C#中的类型安全集合中存储具有约束泛型类型的Action代理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆