1

ここから101個のLinqチュートリアルをコーディングしています。

http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

ほとんどの例は単純ですが、これは私をループに投げ込みました:

    [Category("Ordering Operators")]
    [Description("The first query in this sample uses method syntax to call OrderBy and ThenBy with a custom comparer to " +
                 "sort first by word length and then by a case-insensitive sort of the words in an array. " +
                 "The second two queries show another way to perform the same task.")]
    public void Linq36()
    {
        string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry", "b1" };

        var sortedWords =
            words.OrderBy(a => a.Length)
                 .ThenBy(a => a, new CaseInsensitiveComparer());

        // Another way. TODO is this use of ThenBy correct? It seems to work on this sample array.
        var sortedWords2 =
            from word in words
            orderby word.Length
            select word;

        var sortedWords3 = sortedWords2.ThenBy(a => a, new CaseInsensitiveComparer());

どの単語の組み合わせを投げても、長さは常に最初の順序付けの基準です... 2番目のステートメント(orderbyなし!)が元のorderby句が何であるかをどのように知っているかはわかりませんが。

私は夢中になりますか?Linqが元の順序をどのように「記憶」しているかを誰かが説明できますか?

4

3 に答える 3

5

の戻りタイプはでOrderByはありませんIEnumerable<T>。ですIOrderedEnumerable<T>。これは、与えられたすべての順序を「記憶」するオブジェクトであり、変数を元に戻す別のメソッドを呼び出さない限り、IEnumerableその知識は保持されます。

詳細については、JonSkeetsのすばらしいブログシリーズEdulingを参照してください。Edulingでは、Linq-to-objectsを再実装しています。OrderBy/の主要なエントリは次のThenByとおりです。

于 2012-12-27T19:53:16.897 に答える
1

これは、LINQが遅延しているためです。最初の評価は、シーケンスを列挙した場合にのみ行われます。構築された式ツリーが実行されます。

于 2012-12-27T19:58:38.570 に答える
1

延期された実行の性質を考慮していないため、あなたの質問は表面上はあまり意味がありません。どちらの場合も、正直に「覚えている」わけではなく、本当に必要になるまで実行されません。デバッガーで例を実行すると、これらが同一の(構造的にとにかく)ステートメントを生成することがわかります。検討:

var sortedWords =
        words.OrderBy(a => a.Length)
             .ThenBy(a => a, new CaseInsensitiveComparer());

OrderBy、ThenByに明示的に指示しました。各ステートメントは、すべて完了するまで積み重ねられ、finallyクエリは(psuedo)のように構築されます。

 Select from sorted words, order by length, order by comparer

次に、準備が整うと、実行されてに配置されsortedWordsます。今考えてみましょう:

var sortedWords2 =
        from word in words
        orderby word.Length   // You're telling it to sort here
        select word;

// Now you're telling it to ThenBy here
var sortedWords3 = sortedWords2.ThenBy(a => a, new CaseInsensitiveComparer());

そして、それらのクエリが積み上げられると、それが実行されます。ただし、必要になるまで実行されません。sortedWords3それの必要性が延期されるので、あなたがそれに基づいて行動するまで、実際には何の価値もありません。したがって、どちらの場合も、基本的にコンパイラに次のように言っています。

  1. クエリの作成が完了するまで待ちます
  2. ソースから選択
  3. 長さで並べ替え
  4. それから比較者によって
  5. OK、あなたのことをしてください。

注:要約すると、LINQは「記憶」しません。実行するように指示するまで、LINQは実行されません。次に、それらをクエリにスタックし、必要なときに一度にすべて実行します。

于 2012-12-27T20:01:35.317 に答える