c# - 哪个是创建捕获变量/闭包的代码?

标签 c# .net clr dynamic-language-runtime

我知道变量捕获是由编译器完成的,而不是由 .NET 框架本身中的类完成的。然而,当引入 DLR 时,其中一些工作肯定需要在框架内完成,以便将其推迟到运行时。

例如,在下面给出的代码片段中:

dynamic d = ...

Func<int, bool> func = n => n > d;

变量 d 的类型解析及其是否为整数的验证必须在运行时完成。由于 d 是 lambda 包含方法中的一个变量,它将被捕获到一个闭包中。这部分肯定会在运行时完成。

因此,我推断一定有某些 DLR 程序集(主要是 System.Core.dll)执行此部分操作。

我一直在搜索,我可以找到一些看起来可疑地应受谴责的类来完成这类任务。具体来说,ExpressionQuoter (尽管看起来,这个类并不像 Expression.Quote 方法那样引用 lambda 表达式),HoistedLocals , 和 VariableBinder .

我想我会邀请更了解的人来回答这个问题。

.NET 框架的哪个类或部分将包含 lambda 方法(或匿名方法)的局部变量转换为具有表示它们的静态变量的独立类?

最佳答案

Which class or part of the .NET framework turns locals that are in containing methods of lambdas (or anonymous methods) into those separate classes that have static variables representing them?

不,是编译器在做这项工作。

How would the values of the variables be passed to the separate method? The only way to do this is to define a new helper class that also defines a field for each value that you want passed to the callback code. In addition, the callback code would have to be defined as an instance method in this helper class. Then, the UsingLocalVariablesInTheCallbackCodemethod would have to construct an instance of the helper class,initialize the fields fromthe values in its local variables, and then construct the delegate objectbound to the helper object/instance method.

This is very tedious and error-prone work, and, of course, the C# compiler does all this for you automatically

来自本书CLR Via C#

使用您的代码,生成的类如下所示:

class SomeClass
{
    public dynamic d;
    public bool yourCallBack(int n)
    {
        return n > d;
    }
}

你的代码被编译成类似这样的东西:

dynamic d = ...
SomeClass class1= new SomeClass(); 
class1.d = d;
Func<int, bool> func = class1.yourCallBack;

还有一个关于捕获变量生命周期的说明:

When a lambda expression causes the compiler to generate a class with parameter/local variables turned into fields, the lifetime of the objects that the variables refer to are lengthened. Usually, a parameter/local variable goes out of scope at the last usage of the variable within a method. However, turning the variable into a field causes the field to keep the object that it refers to alive for the whole lifetime of the object containing the field. This is not a big deal in most applications, but it is something that you should be aware of.

关于c# - 哪个是创建捕获变量/闭包的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31625952/

相关文章:

c# - 可以动态执行图像操作的图像 API/应用程序?

c# - 以编程方式使用免费代理服务器连接到网站

c# - 没有 System.Web 的 HTML 解码

clr - 计算 .NET 程序集中 RVA 的文件偏移量

c# - 使用 ReadLineAsync 进行客户端-服务器通信是否完全可以

c# - 更新 PartialView mvc 4

c# - AuthorizeAttribute 和 POST 异步

.net - 托管堆和GC堆有什么区别

c# - 向类中的每个方法添加方法调用

c# - 如何将这些东西放入 C# 中的 linq 中?