我想知道当前的代表签名。
特别是我想将“动作”和“Func”分类。
喜欢,如果当前委托是动作,则运行动作并返回当前值,
如果是func,则运行func并返回func的结果。
答案 0 :(得分:1)
要检查委托是否返回void,您可以检查
bool isVoid = myDelegate.Method.ReturnType == typeof(void);
要专门测试委托是否为Action
,您可以使用
bool isActionT1_T2 = myDelegate.GetType().GetGenericTypeDefinition() == typeof(Action<,>);
这将匹配任何Action<T1, T2>
(具有两个泛型类型参数)。您可以对Func<T1, RetType>
以及其他参数计数执行相同的操作。
答案 1 :(得分:1)
不确定它是最好的还是唯一的方式,但是如果你有类型,你可以寻找.Invoke
方法:
Type type = ...
if(type.IsSubclassOf(typeof(Delegate)))
{
var method = type.GetMethod("Invoke");
foreach(var arg in method.GetParameters())
{
Console.WriteLine(arg.Name + ": " + arg.ParameterType.ToString());
}
Console.WriteLine("returns: " + method.ReturnType.ToString())
}
.ReturnType
将是typeof(void)
。
如果您拥有委托的实例,则可以对委托本身的.Method
属性执行相同的操作:
Delegate instance = ...
var method = instance.Method;
foreach(var arg in method.GetParameters())
{
Console.WriteLine(arg.Name + ": " + arg.ParameterType.ToString());
}
Console.WriteLine("returns: " + method.ReturnType.ToString());
重新:
喜欢,如果当前委托是动作,则运行动作并返回当前值,
你可以特殊情况:
if(instance is Action) {
((Action)instance)();
} else {
//...
}
但是,如果处理任意代表,您可能需要经常使用DynamicInvoke
。
答案 2 :(得分:0)
你可能想要这样的东西:
static void InspectDelegate(object obj)
{
if (!(obj is Delegate del))
return;
var returnType = del.Method.ReturnType.Name;
var parameters = del.Method.GetParameters();
Dictionary<string, string> argNames =
parameters.ToDictionary(a => a.Name, b => b.ParameterType.Name);
if (obj is Action<string, int>)
del.DynamicInvoke("foo", 2);
}
static void Main(string[] args)
{
Action<string, int> act = (x, y) => { Console.WriteLine("x={0}, y= {1}", x, y); };
InspectDelegate(act);
}