C#反射返回方法的内容为委托

时间:2018-07-31 09:21:05

标签: c# unity3d methods reflection

我正在一个具有Abilities类中预先编写的功能并且还处理运行时方法的功能系统上,因此我也将委托用于lambda表达式。 显然,我需要使用反射调用预写方法。

我使用包装方法的委托:

public delegate void AbilityAction();

Abilities类包含所有Ability-Methods。

我要将以下部分设为静态:

var mi = Abilities.instance.GetType ().GetMethod (abilities[i].name, BindingFlags.Instance | BindingFlags.NonPublic) as MethodInfo; 

AbilityAction code = (AbilityAction)Delegate.CreateDelegate(typeof(AbilityAction), this, mi);

然后调用它:

AbilityAction code = GetMethodInClass(abilities[i].name /*e.g. MegaJump*/, Abilities, AbilityAction);

我已尽力而为,但它给了我错误:

约束不能是特殊类'System.Delegate'

public static Delegate GetMethodInClass<T, D>(string methodName, T sourceClass, D delegateType) where D : Delegate {
    var mi = sourceClass.GetType().GetMethod (methodName, BindingFlags.Instance | BindingFlags.NonPublic) as MethodInfo;    
    return (D)Delegate.CreateDelegate(typeof(delegateType), this, mi);
}

谢谢。

1 个答案:

答案 0 :(得分:2)

在没有委托类型和示例方法的情况下,我看不到您实际上是在做什么,但是...尽可能地在两行之间阅读,这是一个类似的示例,作品:

using System;
using System.Reflection;

class Foo
{

    public int Bar(string whatever) => whatever.Length;
}

delegate int AbilityAction(string name);
static class Program
{


    static void Main(string[] args)
    {
        var foo = new Foo();
        var action = GetMethodInClass<AbilityAction>(nameof(foo.Bar), foo);

        int x = action("abc");
        Console.WriteLine(x); // 3
    }

    public static D GetMethodInClass<D>(string methodName, object target) where D : Delegate
    {
        var mi = target.GetType().GetMethod(methodName,
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        return (D)Delegate.CreateDelegate(typeof(D), target, mi);
    }
}

注意:如果您没有C#7.3,则该方法需要进行一些细微调整:

    public static D GetMethodInClass<D>(string methodName, object target) where D : class
    {
        var mi = target.GetType().GetMethod(methodName,
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        return (D)(object)Delegate.CreateDelegate(typeof(D), target, mi);
    }