var x = 1;
Func<int,int> f = y => x + y;
x = 2;
Console.WriteLine(f(1));
出力は 3 です。https://web.archive.org/web/20170426121932/http://www.cs.cornell.edu/~clarkson/courses/csci4223/2013sp/lecによると、2 であると想定します。 /lec12.pdf
var x = 1;
Func<int,int> f = y => x + y;
x = 2;
Console.WriteLine(f(1));
出力は 3 です。https://web.archive.org/web/20170426121932/http://www.cs.cornell.edu/~clarkson/courses/csci4223/2013sp/lecによると、2 であると想定します。 /lec12.pdf
PDF が完全に説明していないレキシカル スコープに関する微妙な点があります。その例には、実際には という名前の 2 つの異なる変数がx
あり、最初の値を再割り当てしませんx
(実際、関数型言語は変更を許可しない場合があります)。
C# はレキシカル スコープx
です。デリゲートが呼び出されたときではなく、ラムダの定義の時点で検索します。ただしx
、値ではなく変数に解決され、呼び出し時に変数の値が読み取られます。
より完全な例を次に示します。
int InvokeIt( Func<int, int> f )
{
int x = 2;
return f(1);
}
Func<int, int> DefineIt()
{
int x = 1;
Func<int, int> d = (y => x + y);
x = 3; // <-- the PDF never does this
return d;
}
Console.WriteLine(InvokeIt(DefineIt()));
ラムダは、内部に存在するx
変数にバインドします。定義時の値 ( ) は関係ありません。変数は後で に設定されます。 DefineIt
x = 1
x = 3
しかし、内部が使用されていないため、明らかに動的スコープでもありません。x = 2
InvokeIt