如何找出代表返回无效?

时间:2017-06-19 08:58:54

标签: c# reflection delegates action func

我想知道当前的代表签名。

特别是我想将“动作”和“Func”分类。

喜欢,如果当前委托是动作,则运行动作并返回当前值,

如果是func,则运行func并返回func的结果。

3 个答案:

答案 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);
 }