ここで混乱することがいくつかあります。
レイトバインディング:コードの意味は、コンパイル後に決定されます。例えば、x.DoStuff()
は、x
の型のオブジェクトがDoStuff()
メソッド(拡張メソッドとデフォルトの引数も考慮して)を持っていることをコンパイラがチェックし、それが出力するコードでその呼び出しを生成するか、コンパイラで失敗した場合に、それ以外の場合はエラーです。実行時にDoStuff()
メソッドの検索が実行され、DoStuff()
メソッドがない場合は実行時例外がスローされます。それぞれの長所と短所があります.C#は通常早期バインドされていますが、遅延バインディング(最も簡単にはdynamic
を介してサポートされていますが、反射を含むより複雑なアプローチもカウントされます)。
遅延実行厳密に言えば、すべてのLinqメソッドはただちに結果を生成します。しかし、その結果は、それ自体が列挙されているときに適切な方法で処理される、列挙可能なオブジェクトへの参照を格納するオブジェクト(前のLinqメソッドの結果であることが多い)です。例えば、我々は我々自身Take
メソッドを書くことができますように:
var taken4 = someEnumerable.Take(4);//taken4 has a value, so we've already done
//something. If it was going to throw
//an argument exception it would have done so
//by now.
var firstTaken = taken4.First();//only now does the object in taken4
//do the further processing that iterates
//through someEnumerable.
キャプチャ変数::私たちは、変数を利用する際、通常、私たちが利用することが、我々はそれを使用今
private static IEnumerable<T> TakeHelper<T>(IEnumerable<T> source, int number)
{
foreach(T item in source)
{
yield return item;
if(--number == 0)
yield break;
}
}
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, int number)
{
if(source == null)
throw new ArgumentNullException();
if(number < 0)
throw new ArgumentOutOfRangeException();
if(number == 0)
return Enumerable.Empty<T>();
return TakeHelper(source, number);
}
、それは、これが2
とを印刷していることはかなり直感的です
int i = 2;
string s = "abc";
Console.WriteLine(i);
Console.WriteLine(s);
i = 3;
s = "xyz";
:どのように現在の状態のであり、3
およびxyz
ではない。
int i = 2;
string s = "abc";
Action λ =() =>
{
Console.WriteLine(i);
Console.WriteLine(s);
};
i = 3;
s = "xyz";
λ();
作成を:我々は、変数として、それを「キャプチャ」されている変数を利用して、そして私たちは、それはデリゲートが呼び出されたときに持っている値を使用して終了しますけれども、匿名関数とラムダ式では、 λ
はi
とs
の値を使用しますが、λ
が呼び出されたときにi
とs
をどうするかのような命令セットを作成しません。その場合にのみ、i
とs
の値が使用されます。
全部まとめて:いずれの場合でも、遅延バインディングはありません。それはあなたの質問に無関係です。
両方とも実行が遅延しています。 Take
への呼び出しとWhere
への呼び出しの両方が列挙されるときにarr
で動作する列挙可能なオブジェクトを返します。
キャプチャされた変数は1つだけです。 Take
への呼び出しは、その値を利用する整数をTake
とTake
に直接渡します。 Where
の呼び出しは、ラムダ式から作成されたFunc<int, bool>
を渡し、ラムダ式はint
という変数を取り込みます。 Where
はこのキャプチャについて何も知らないが、Func
はそうである。彼らはcutoff
をどのように扱うかで二つはとても異なる挙動を示す理由です
。
これは遅いバインディングとは関係ありません。 –