我有一个委托集合:
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(泛型)方法正在使用它,因此这里使用泛型类型
**根据这里的答案
这不是最漂亮的东西,但它有效
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
不会改变这一点。