【问题标题】:Create Delegate from MethodInfo with Output Parameters, without Dynamic Invoke使用输出参数从 MethodInfo 创建委托,无需动态调用
【发布时间】:2020-06-22 13:20:59
【问题描述】:

我正在尝试从具有输出参数的 MethodInfo 对象中获取委托。我的代码如下:

static void Main(string[] args) {

        MethodInfo m = typeof(Program).GetMethod("MyMethod2");

        IEnumerable<Type> paramsTypes = m.GetParameters().Select(p => p.ParameterType);

        Type methodType = Expression.GetDelegateType(paramsTypes.Append(m.ReturnType).ToArray());

        Delegate d = m.CreateDelegate(methodType);

        Action a = (Action)d;

        a();

    }

我得到的是 System.InvalidCastException: Unable to cast object of type Delegate2$1 to type System.Action 在执行“Action a = (Action)d”的行中。问题是我不知道在 Action 中放入什么类型,因为我知道正确的类型不是 String,它是编译中 String (String&) 的输出等价物。

MyMethod2 有一个输出参数,我认为这就是问题所在,因为当我使用作为输入参数的 MyMethod 进行测试时,它可以工作。

public static void MyMethod2(out String outputParameter) {

        outputParameter = "hey";

    }

public static void MyMethod(String inputParameter) {

  //does nothing 
    
}

另外,我知道如果我使用 Dynamic Invoke 而不是普通的 Delegate 调用会更容易,但我对此不感兴趣,因为我正在尝试提高我的程序的性能。有谁知道如何做到这一点?谢谢

【问题讨论】:

    标签: c# .net lambda reflection delegates


    【解决方案1】:

    没有没有FuncAction 可以使用out 参数。不过,您可以轻松声明自己的委托类型:

    public delegate void OutAction<T>(out T arg)
    

    然后你可以使用

    OutAction<string> action = (OutAction) m.CreateDelegate(typeof(OutAction<string>));
    

    您将无法使用 Expression.GetDelegateType,因为它仅支持 FuncAction,但您可以编写自己的等效项以根据参数计算出要使用的正确 OutAction&lt;&gt; 类型,如果您需要动态进行。

    【讨论】:

    • 谢谢你的回答:)。当你声明我应该使用'public delegate void OutAction...'的类型时,对吗?
    • @fobisthename:抱歉,是的,这是一个错字 - 现在已修复。
    • 另外,您是否知道是否有一种方法可以使用 OutAction 之类的东西来创建委托,而无需事先知道参数的数量及其类型?我的意思是最终代表的签名。
    • @fobisthename:我不确定你的意思。正如我在答案中所说,您可以自己编写 Expression.GetDelegateType 之类的内容,使用泛型创建委托类型 - 但您将无法像在原始代码中那样cast .不幸的是,除了您的问题之外,我们没有您想要做什么的背景。
    • @fobisthename:所以在您的实际代码中,您永远不会强制转换为特定的委托类型。如果您对这些方法没有 概念(因此它可能有五个参数,例如其中三个是 out 参数),那么您需要声明大量的委托类型。我不认为那会很好用。但是,如果您可以将其限制为一组特定的签名(仍然是通用的,并且每个方法可能允许 一个 参数,始终是最后一个),那么它可以完成。
    猜你喜欢
    • 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
    相关资源
    最近更新 更多