3

testit() メソッドはクロージャです。aString は範囲外ですが、testit() は引き続き実行できます。testit2() は、スコープ (mystring) から外れていないが、testit2() にも渡されていない変数を使用しています。testit2() は閉鎖と見なされますか?

string mystring = "hello world";
Action testit = new Action(delegate { string aString = "in anon method"; Debug.WriteLine(aString); });
testit();

//capture mystring.  Is this still a closure?
Action testit2 = new Action(delegate { Debug.WriteLine(mystring); });
//mystring is still in scope
testit2();

2 番目の例では、mystring はメソッドの外部で更新でき、それらの変更は testit2() に反映されます。これは、mystring をパラメーターとしてキャプチャすることしかできない通常の方法とは異なります。

4

3 に答える 3

6

どちらの例も無名関数です。2 つ目は、ローカル変数をキャプチャするためにクロージャを使用します。無名関数に関する変数の有効期間は、それを使用するためにクロージャーが作成されるかどうかには影響しません。変数が無名関数の外部で定義され、内部で使用されている限り、クロージャが作成されます。

最初の無名関数はローカル状態を使用しないため、クロージャーは必要ありません。静的メソッドにコンパイルする必要があります。

これは、無名関数が現在の関数の有効期間を超えて存続できるため必要です。したがって、匿名関数で使用されるすべてのローカルは、後でデリゲートを実行するためにキャプチャする必要があります。

于 2009-02-16T19:48:56.360 に答える
3

クロージャはスコープ内のをキャプチャするのではなく、スコープの実際の定義をキャプチャします。したがって、同じスコープへの参照を持つ他のコードは、その中の変数を変更できます。

于 2009-02-16T19:50:02.193 に答える
1

testitは実際ほどクロージャーではありません。 「親」環境 ( など) の変数ではなく、ローカルで定義されtestit2た変数のみを使用しています。mystring

ただし、匿名メソッドにより、囲んでいる環境から変数をキャプチャする機能があるため、どちらもクロージャーであると私は主張します。

于 2009-02-16T19:50:59.320 に答える