【问题标题】:Create C# delegate type with ref parameter at runtime在运行时使用 ref 参数创建 C# 委托类型
【发布时间】:2023-04-05 12:32:01
【问题描述】:

我需要在运行时创建一个带有ref 参数的委托类型。

如果我在编译时知道参数类型,我可以使用显式委托类型声明,例如:

// S is some struct / value type, e.g. int or Guid
delegate void VoidDelSRef (ref S s);
Type td = typeof (VoidDelSRef);

该类型 td 用于创建 C#4 表达式树,该树被编译为委托。

由于我的表达式树中的代码修改了参数s,所以我需要通过引用传递s

我必须支持任何类型S,所以我不能使用显式委托类型声明,因为我只有Type ts = typeof (S) 及其ref 类型Type tsr = ts.MakeByRefType ()

我尝试使用Expression.GetActionType (tsr),但它不允许使用ref 类型。

如何在运行时使用ref 参数构建委托?

【问题讨论】:

    标签: dynamic parameters delegates pass-by-reference


    【解决方案1】:

    在 .NET 4 中,您可以使用 Expression.GetDelegateType 方法。与GetActionType 不同,它适用于ByRef 类型。

    例如:

    // void MyDelegate(ref int arg)
    var delType = Expression.GetDelegateType(typeof(int).MakeByRefType(), 
                                             typeof(void));
    

    如果您使用的是 .NET 3.5,则此方法不可用。如果你想复制它的功能,我建议看看它的实现(使用反编译器)。它没有太多的依赖关系;这绝对是可行的。

    【讨论】:

    • 嗯,它工作 - 几乎。 GetDelegateType 创建我需要的类型。所以阿尼完全回答了我的问题。但是,我仍然有一些问题要调用代表。但我仍在分析到底发生了什么。我注意到 GetDelegateType 的一些意外行为:当使用完全相同的参数多次调用时,每次调用都会返回新的类型实例,因此它们不是引用相等的。这里有更多信息:DLR @ CodePlex - Bug with Expression.GetDelegateType and user defined struct as ref。当我知道要问什么时我会回来的:)
    • 我想我现在明白我的问题了。在构建表达式树的函数中,我使用Expression.GetDelegateType() 指定委托类型。但是我不能将编译后的委托转换为VoidDelSRef,很可能是因为每个 GetDelegateType 返回一个新的类型实例。所以我这样称呼代表 dlg:S s = new S (); var dpl = new object[] { s }; dlg.DynamicInvoke (dpl); s = (S) dpl[0];。我猜效率略低,但现在可以了:)
    猜你喜欢
    • 1970-01-01
    • 2014-03-08
    • 2021-12-19
    • 1970-01-01
    • 2010-12-25
    • 2016-08-07
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    相关资源
    最近更新 更多