如何根据C#中参数的泛型类型过滤委托集合?

时间:2015-05-31 21:20:06

标签: c# linq generics delegates

我有一组代表:

IList<Action<ISomeInterface>> _delegates = new List<Action<ISomeInterface>>();

一个方法*将代理添加到它**:

public void AddDelegate<T>(Action<T> del) where T : ISomeInterface
{
    _delegates.Add(si => del((T)si));   
}

现在我想根据构造委托的具体类型过滤委托集合:

var aDelegates = _delegates.Where(d => d is Action<SomeInterfaceImplA>);
foreach(var del in aDelegates)
{
   ....
}

这将返回所有代表,而不仅仅是Action<SomeInterfaceImplA>个代表。所以我的问题是,应该在Where子句中使用什么谓词来从过滤中获取正确的子集?完整的代码示例可用here *一个流利的API(通用)方法正在使用它因此在这里使用泛型类型
**基于答案here

2 个答案:

答案 0 :(得分:1)

这不是最漂亮的东西,但它有效

    var aDelegates = someClass.Delegates.Where(d => 
        d.Method.DeclaringType.GenericTypeArguments.FirstOrDefault().IsAssignableFrom(typeof(SomeInterfaceImplA)));

答案 1 :(得分:1)

我不确定你目前的构造是否有意义。如果要通过具体的预期实现参数类型过滤代理,可能需要更改正在执行的操作,方法是:

IList<Action<ISomeInterface>> _delegates = new List<Action<ISomeInterface>>();

到此:

IDictionary<Type, List<Action<ISomeInterface>>> _delegates = 
    new Dictionary<Type, List<Action<ISomeInterface>>>();

AddDelegate方法

public void AddDelegate<T>(Action<T> del) where T : ISomeInterface
{
    var list = default(List<Action<ISomeInterface>>);
    if (!_delegates.TryGetValue(typeof(T), out list))
        _delegates[typeof(T)] = list = new List<Action<ISomeInterface>>();
     list.Add(si => del((T)si));   
}

并使用字典按参数类型进行过滤。

您当前代码无效的原因是,所有已注册的操作实际上都是Action<ISomeInterface>类型,其方法体(si => del((T)si)执行危险将其参数强制转换为类型T并不会改变它。