クエリ式は、通常は、拡張メソッドの呼び出しに変換されます。 (彼らはがするを持っていませんが、クエリの99.9%がIEnumerable<T>
またはIQueryable<T>
を使用しています。)
そのメソッドが何をするかの正確なアルゴリズムはメソッドからメソッドに変わります。サンプルクエリではハッシュテーブルは使用されませんが、ジョインやグループ化操作などがあります。述語が提供され
public static IEnumerable<T> Where(this IEnumerable<T> source,
Func<T, bool> predicate)
{
// Argument checking omitted
foreach (T element in source)
{
if (predicate(element))
{
yield return element;
}
}
}
:
シンプルWhere
コールは、(私は承知している限り、現時点ではVBで利用できない反復子ブロックを、使用して)C#でこのような何かに変換しますデリゲート(またはIQueryable<T>
を使用している場合は式ツリー)を呼び出し、シーケンス内の各アイテムに対して呼び出されます。結果はストリーミングされ、実行は延期されます。つまり、結果から項目を要求するまでは何も起こりません。さらに次の結果を得るために必要なだけの処理を行います。いくつかの演算子は、(シーケンスの代わりに単一の値を返す基本的なものを)延期されていないといくつかの入力をバッファ(例えばReverse
は、それがどんな結果を返すことができます前に、最後の結果はそれを読み取るため、シーケンスの最後まで読まなければなりません最初に収穫しなければならないものです)。
それは、私は怖いが、あなたは特定のものについて質問がある場合、私たちは義務付けることができると確信していひとつひとつのLINQ演算子の詳細を与えるために、単一の答えの範囲を超えています。
LINQ to SQLまたはIQueryable<T>
に基づいた別のプロバイダを使用している場合は、状況がかなり異なることを付け加えておきます。 Queryable
クラスは、(IQueryable<T>
を実装するプロバイダの助けを借りて)クエリを構築し、その後、クエリは一般にプロバイダによってより適切な形式(例えばSQL)に変換される。正確な詳細(バッファリング、ストリーミングなどを含む)は完全にプロバイダに依存します。
恐ろしいです。素晴らしい返信。ありがとう、ジョン。 – Daniel