【问题标题】:Getting a delegate from methodinfo从 methodinfo 获取委托
【发布时间】:2009-06-02 16:58:13
【问题描述】:

我有一个下拉列表,它通过检查类的方法并包括与特定签名匹配的方法来填充。问题在于从列表中获取所选项目并让委托在类中调用该方法。第一种方法有效,但我无法弄清楚第二种方法的一部分。

例如,

public delegate void MyDelegate(MyState state);

public static MyDelegate GetMyDelegateFromString(string methodName)
{
    switch (methodName)
    {
        case "CallMethodOne":
            return MyFunctionsClass.CallMethodOne;
        case "CallMethodTwo":
            return MyFunctionsClass.CallMethodTwo;
        default:
            return MyFunctionsClass.CallMethodOne;
    }
}

public static MyDelegate GetMyDelegateFromStringReflection(string methodName)
{
    MyDelegate function = MyFunctionsClass.CallMethodOne;

    Type inf = typeof(MyFunctionsClass);
    foreach (var method in inf.GetMethods())
    {
        if (method.Name == methodName)
        {
            //function = method;
            //how do I get the function to call?
        }
    }

    return function;
}

如何使第二种方法的注释掉部分起作用?如何将MethodInfo 投射到委托中?

谢谢!

编辑:这是可行的解决方案。

public static MyDelegate GetMyDelegateFromStringReflection(string methodName)
{
    MyDelegate function = MyFunctionsClass.CallMethodOne;

    Type inf = typeof(MyFunctionsClass);
    foreach (var method in inf.GetMethods())
    {
        if (method.Name == methodName)
        {
            function = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), method);
        }
    }

    return function;
}

【问题讨论】:

    标签: c# reflection delegates


    【解决方案1】:
    public static Delegate CreateDelegate(this MethodInfo methodInfo, object target) {
        Func<Type[], Type> getType;
        var isAction = methodInfo.ReturnType.Equals((typeof(void)));
        var types = methodInfo.GetParameters().Select(p => p.ParameterType);
    
        if (isAction) {
            getType = Expression.GetActionType;
        }
        else {
            getType = Expression.GetFuncType;
            types = types.Concat(new[] { methodInfo.ReturnType });
        }
    
        if (methodInfo.IsStatic) {
            return Delegate.CreateDelegate(getType(types.ToArray()), methodInfo);
        }
    
        return Delegate.CreateDelegate(getType(types.ToArray()), target, methodInfo.Name);
    }
    

    【讨论】:

    • @Graviton 取决于您是否碰巧将方法签名作为Delegate 类型。在这种情况下,OP 似乎表明他可以预先假设MyDelegate,在这种情况下,Nate 和 OP 合并的解决方案是最好的。另一方面,这个问题是 other 问题的绝佳答案,如果您无法访问适当的 Delegate 类型(即通常,您获得了 @987654325 @ 仅凭名字就出乎意料)...但正是需要这样的委托类型才能创建委托(有点臭名昭著的.NET鸡和蛋问题)。
    • 此方案不适用于带有 out / ref 参数类型的方法。
    • 我注意到该方法被标记为private。除非您真的想将其用作扩展方法,否则应将其声明为public
    • @ArsenKhachaturyan 你是对的,可能是复制/粘贴问题。
    【解决方案2】:

    您需要调用某种形式的Delegate.CreateDelegate(),具体取决于所讨论的方法是静态方法还是实例方法。

    【讨论】:

    • 这个答案有一个例子会更有帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-03-02
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多