如何在c#中根据委托的参数's泛型类型过滤委托集合

本文关键字:泛型类型 集合 过滤 参数 | 更新日期: 2023-09-27 17:52:16

我有一个委托集合:

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子句中应该使用什么谓词来从过滤中获得正确的子集?完整的代码示例可以在这里找到。
*一个流畅的API(泛型)方法正在使用它,因此这里使用泛型类型
**根据这里的答案

如何在c#中根据委托的参数's泛型类型过滤委托集合

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

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

我不确定您目前的结构是否有任何意义。如果你想通过具体的预期实现参数类型来过滤委托,你可能想改变你正在做的事情,通过改变这个:

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不会改变这一点。