当一个对象调用它自己的函数之一时,是否是闭包的情况,其中对象作为第一个变量传递给方法

本文关键字:对象 情况 第一个 方法 变量 是否是 自己的 函数 它自己 调用 一个对象 | 更新日期: 2023-09-27 18:34:08

我想我理解闭包是如何在C#和.NET中实现的。当 CLR 检测到函数将传递到其作用域之外并作用于自由变量时,它会将该函数和变量打包到自定义类中。

那么,这与object调用自己的函数时发生的情况有何不同呢?object本身作为第一个变量传递到函数中,以便如果函数需要对象的任何其他函数、属性或字段,它都可以访问它们。

我想我在这里遗漏了一些东西,并希望对这两种情况下发生的事情进行某种解释:闭包,以及对象调用自己的方法之一的情况。

当一个对象调用它自己的函数之一时,是否是闭包的情况,其中对象作为第一个变量传递给方法

对对象的常规方法调用与闭包无关;只有将该方法调用打包为委托,您才有一个闭包!

为了理解正在发生的事情,你需要很好地掌握"值类型"和"引用类型"的概念。在 .net 中谈论Object不够明确,因为Object在所有内容(包括值类型(的层次结构中都处于底部(int也是一个Object(。开始考虑对纯引用类型(如类实例(进行方法调用要容易得多。

以普通类变量和实例化为例:

List x; // variable declaration
x = new List(); // instantiation

或者,在一行上:

List x = new List();

实例的"正文"将保留在称为堆的内存区域中。您正在使用的x仅包含对该内存区域的引用,这就是为什么这被称为 reference type .

当您使用 x 变量在List上调用方法时,该方法需要知道在哪个列表中工作。因此,该方法只是获取对该实例主体的引用作为第一个参数,即this参数。说 CLR 或编译器传递"对象"是不正确的,因为对象始终在堆上,它只传递引用(或指针(。

当该方法需要调用同一对象的不同方法时,它只需传递与第一个参数相同的this,即它自己接收的参数。

普通方法调用如下所示:

x.Add(Something); // calls instance method "Add" on "x"

当编译器看到它知道引用以使用 x 作为调用Addthis(第一个参数,隐藏参数(时。那里没有"关闭"!

闭包的样子如下:

List<int> A = new List<int>();
List<int> B = new List<int>();
Action<int> aDelegate; // <-- declare a delegate type variable
                       //   Action<int> is a delegate that returns void and
                       //   takes a single int parameter.
aDelegate = A.Add; // <-- initialize the delegate using an instance method of object A
aDelegate(7); // <- notice the call! No reference to "A" because "A" is already stored in aDelegate
aDelegate = B.Add;
aDelegate(8); // <- notice the call! No reference to "B" because "B" is already stored in aDelegate

如果你仔细观察调用委托(aDelegate(7)(时会发生什么,编译器不知何故需要在对象A上调用Add方法,但你看不到,它是隐藏的。委托封装了对对象A的引用和Add方法的地址,这就是它被称为closure的原因。为了对比,看看当你做aDelegate(8)时会发生什么;这个时间方法Add是在对象B上调用的,但无法猜测,因为同样,对对象B的引用被埋在委托(闭包(中。

相关文章: