在c#中,确定对象o是否为动作<…>或Func< . .祝辞
本文关键字:祝辞 Func 是否 对象 | 更新日期: 2023-09-27 18:11:55
假设你有一个字典<字符串,对象>。它可能包含小数、字符串或其他有效类型。它还可以包含Actions和Funcs,如:
Action<string> or Action<int,int,string> etc.
是否有一种通用的方法来发现一个给定的键k指向一个动作或函数,然后调用相同的值?
var value = dict[key];
//some sort of predicate checking if value is invokeable
我考虑过使用动态关键字并对结果对象简单地调用Invoke(args),但这似乎很慢而且不美观。
你可以测试它是一个委托:
Delegate d = value as Delegate;
if(d != null) d.DynamicInvoke(args);
然而!如果您在调用之前不知道签名,那么要知道(在对象数组中)提供什么参数是很棘手的。
如果您不想通过动态或委托动态调用它。DynamicInvoke,您可以使用一些通用的扩展方法来为您执行测试。
首先,将你的字典命名为Dictionary<whatever,>而不是object。
接下来,创建两个扩展方法(或更多,以匹配您所关心的委托类型)。
public static bool TryInvoke<T>(this Delegate del, T arg)
{
var action = del as Action<T>;
if (action != null)
{
action(arg);
return true;
}
return false;
}
public static bool TryFunc<T, TResult>(this Delegate del, T arg, out TResult result)
{
result = default(TResult);
var func = del as Func<T, TResult>;
if (func != null)
{
result = func(arg);
return true;
}
return false;
}
最后,像这样使用扩展方法…
var value = dict[key];
if (value.TryInvoke(20))
{
// do something...
}
else
{
int result;
if (value.TryInvoke(20, out result))
{
// do something else...
}
}
不难想象把它构建成一个小库并重新使用。