如何从MethodInfo的创建委托时,方法签名不能事先知道? [英] How to create a delegate from a MethodInfo when method signature cannot be known beforehand?

查看:191
本文介绍了如何从MethodInfo的创建委托时,方法签名不能事先知道?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个方法,需要一个的MethodInfo 实例重新presenting非泛型静态方法与任意的签名,并返回绑定到该方法可稍后委托使用 Delegate.DynamicInvoke 方法被调用。我的第一天真的尝试是这样的:

I need a method that takes a MethodInfo instance representing a non-generic static method with arbitrary signature and returns a delegate bound to that method that could later be invoked using Delegate.DynamicInvoke method. My first naïve try looked like this:

using System;
using System.Reflection;

class Program
{
    static void Main()
    {
        var method = CreateDelegate(typeof (Console).GetMethod("WriteLine", new[] {typeof (string)}));
        method.DynamicInvoke("Hello world");
    }

    static Delegate CreateDelegate(MethodInfo method)
    {
        if (method == null)
        {
            throw new ArgumentNullException("method");
        }

        if (!method.IsStatic)
        {
            throw new ArgumentNullException("method", "The provided method is not static.");
        }

        if (method.ContainsGenericParameters)
        {
            throw new ArgumentException("The provided method contains unassigned generic type parameters.");
        }

        return method.CreateDelegate(typeof(Delegate)); // This does not work: System.ArgumentException: Type must derive from Delegate.
    }
}

我希望 MethodInfo.CreateDelegate 方法可以计算出正确的委托类型本身。嗯,很明显它不能。那么,如何做我创建的System.Type 重presenting相匹配的签名的委托实例所提供的的MethodInfo 实例?

I hoped that the MethodInfo.CreateDelegate method could figure out the correct delegate type itself. Well, obviously it cannot. So, how do I create an instance of System.Type representing a delegate with a signature matching the provided MethodInfo instance?

推荐答案

您可以使用<一个href="http://msdn.microsoft.com/en-us/library/system.linq.ex$p$pssions.ex$p$pssion.getdelegatetype.aspx">System.Linq.Ex$p$pssions.Ex$p$pssion.GetDelegateType方法:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

class Program
{
    static void Main()
    {
        var writeLine = CreateDelegate(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));
        writeLine.DynamicInvoke("Hello world");

        var readLine = CreateDelegate(typeof(Console).GetMethod("ReadLine", Type.EmptyTypes));
        writeLine.DynamicInvoke(readLine.DynamicInvoke());
    }

    static Delegate CreateDelegate(MethodInfo method)
    {
        if (method == null)
        {
            throw new ArgumentNullException("method");
        }

        if (!method.IsStatic)
        {
            throw new ArgumentException("The provided method must be static.", "method");
        }

        if (method.IsGenericMethod)
        {
            throw new ArgumentException("The provided method must not be generic.", "method");
        }

        return method.CreateDelegate(Expression.GetDelegateType(
            (from parameter in method.GetParameters() select parameter.ParameterType)
            .Concat(new[] { method.ReturnType })
            .ToArray()));
    }
}

有可能是在第二检查复制粘贴错误 method.IsStatic - !你不应该使用 ArgumentNullException 有。它是一个很好的风格,提供一个参数名作为参数传递给的ArgumentException

There is probably a copy-paste error in the 2nd check for !method.IsStatic - you shouldn't use ArgumentNullException there. And it is a good style to provide a parameter name as an argument to ArgumentException.

使用 method.IsGenericMethod 如果你想拒绝所有的通用方法和 method.ContainsGenericParameters 如果你要拒绝只有无取代类型参数泛型方法。

Use method.IsGenericMethod if you want to reject all generic methods and method.ContainsGenericParameters if you want to reject only generic methods having unsubstituted type parameters.

这篇关于如何从MethodInfo的创建委托时,方法签名不能事先知道?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆