DynamicMethod可以访问变量吗?

时间:2013-01-13 00:40:11

标签: c# .net

动态方法是否可以像普通方法或代码一样工作,因为它可以访问通常可以访问变量的变量,调用方法和初始化变量(当然在方法范围内)?

我见过的唯一例子是它传递一些参数并返回一些值,并且不会改变它之外的任何变量。

我在谈论System.Reflection.Emit.DynamicMethod类。我无法理解它,因为我需要使用我还不太了解的MSIL。

1 个答案:

答案 0 :(得分:1)

是。 DynamicMethod可以附加到一个类,在这种情况下,它可以访问类私有静态字段(如果DynamicMethod是一个实例方法,可能会访问类私有字段,但我不记得这是否是受支持的方案)。它还可以访问在创建DynamicMethod的程序集内部的程序集内部方法,属性和类型。

您使用动态方法的场景是什么?

我有一些关于动态编程的博客文章,包括一些关于在我的博客上使用DynamicMethod类的条目:http://robpaveza.net/tag/dynamic-programming。具体来说,this article讨论了如何计算文件修订证明,你可以看到结果实现here(显然,我从来没有写过第2部分,但是我链接的BN中的实现是结果分析)。

让我引导您完成编译方法:

  1. 键入parameterType = typeof(uint).MakeByRefType()
  2. 最后一种方法是取出uint参数;此行获取对uint-ref运行时类型的引用。如果我在普通的C#中编写它,方法声明将如下所示:

    public static void CheckRevision(out uint a, out uint b, out uint c, out uint s);
    

    38-40。 foreach(公式中的字符串公式)CompileStandardFormula(生成器,公式)

    正如我在博客文章中提到的那样,我所做的数学总是以下列形式提供:

    A=A-S B=B-C C=C+A A=A+B
    

    其中A,B和C是状态变量,S是输入(文件中的下一个uint值)。

    CompileStandardFormula函数发出IL,用于计算所示四个操作的单个操作的逻辑。回想一下,CLR是一个基于堆栈的状态机,并且会发生数学运算,并且会弹出堆栈上的值并推送结果。因此,对于A = A-S,例如,下面的IL是将要发出的:

    ldarg.0  // push &A, which is a reference to the location that actually contains the value of A
    ldarg.0  // push &A
    ldind.u4 // dereference the top-most value on the stack, which puts the actual value of &A ready for operation
    ldarg.3  // push &S
    ldind.u4 // dereference &S
    sub      // subtracts [stack-1] from [stack-2], which effectively is A-S
    stind.u4 // remember the first ldarg.0? That's getting accessed now and the subtraction result is going there
    

    所以,在这一点上,我们应该很容易理解:我的DynamicMethod编译了更新文件中单个传递的所有状态变量所需的数学运算。在发出所有IL之后,因为我们知道堆栈的状态没有任何内容(比输入方法时更多),我们可以抛出一个快速的“ret”指令,我们就完成了。

    无论如何,希望这有帮助。