0

C# と .NET でクロージャーがどのように実装されているかを理解していると思います。CLR は、関数がそのスコープ外に渡され、自由変数に作用することを検出すると、関数と変数をカスタム クラスにパッケージ化します。

objectでは、これはがそれ自体の関数の 1 つを呼び出した場合とどのように異なるのでしょうか? それobject自体が最初の変数として関数に渡されるため、関数がオブジェクトの他の関数、プロパティ、またはフィールドのいずれかを必要とする場合、それらにアクセスできます。

私はここで何かが欠けていると思います.クロージャーとオブジェクトが独自のメソッドの1つを呼び出している場合の両方で何が起こっているのかについて何らかの説明をしたいと思います.

4

1 に答える 1

1

オブジェクトに対する通常のメソッド呼び出しは、クロージャーとは何の関係もありません。そのメソッド呼び出しをデリゲートとしてパッケージ化する場合にのみ、クロージャがあります!

何が起こっているのかを理解するには、「値型」と「参照型」の概念をよく理解する必要があります。について話すことObjectは、.net では十分に明確ではありません。これObjectは、値の型を含むすべての階層の最下部にあるためです (intも ですObject)。クラス インスタンスなどの純粋な参照型でのメソッド呼び出しについて考え始める方がはるかに簡単です。

通常のクラス変数とインスタンス化を取り上げます。

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

または、1 行で:

List x = new List();

インスタンスの「本体」は、ヒープと呼ばれるメモリ領域に残ります。作業している はそのxメモリ領域への参照のみを保持するため、これは と呼ばれreference typeます。

List変数を使用してメソッドを呼び出す場合、xメソッドはどのリストで機能するかを知る必要があります。したがって、このメソッドは、最初のパラメーターであるパラメーターとして、インスタンスの本体への参照を取得するだけthisです。オブジェクトは常にヒープ上にあり、参照 (またはポインター) のみを渡すため、CLR またはコンパイラーが「オブジェクト」を渡すと言うのは正しくありません。

そのメソッドが同じオブジェクトの別のメソッドを呼び出す必要がある場合、それthis自体が受け取った最初のパラメーターと同じものを渡すだけです。

通常のメソッド呼び出しは次のようになります。

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

への呼び出しxの (最初のパラメーター、非表示のパラメーター) として使用する参照を知っていることをコンパイラーが認識した場合。そこに「閉鎖」はありません!thisAdd

クロージャーは次のようになります。

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)、コンパイラは何らかの形Addで object のメソッドを呼び出す必要Aがありますが、それは見えず、隠されています。デリゲートは、オブジェクトへの参照とメソッドAのアドレスの両方をカプセル化するため、 . 対照的に、そうすると何が起こるかを見てください。今回は object でメソッドが呼び出されますが、 object への参照がデリゲート (クロージャー) 内に埋め込まれているため、それを推測する方法はありません。AddclosureaDelegate(8)AddBB

于 2013-10-06T05:57:02.687 に答える