次の方法で共有


中間具体化 (C#)

注意しないと、場合によっては、クエリでコレクションが早期に具体化され、アプリケーションのメモリとパフォーマンス プロファイルが大幅に変更される可能性があります。 一部の標準クエリ演算子では、1 つの要素を生成する前にソース コレクションが具体化されます。 たとえば、 Enumerable.OrderBy 最初にソース コレクション全体を反復処理してから、すべての項目を並べ替え、最後に最初の項目を生成します。 これは、順序付けられたコレクションの最初の項目を取得するコストが高くなることを意味します。その後の各項目は高価ではありません。 これは理にかなっています。それ以外の場合、そのクエリ演算子では実行できません。

例: ToListを呼び出し、具体化の原因となるメソッドを追加する

この例では 、チェーン クエリの例 (C#) の例を変更します。 AppendString メソッドは、ソースを反復処理する前に ToList を呼び出すように変更され、具体化が発生します。

public static class LocalExtensions
{
    public static IEnumerable<string>
      ConvertCollectionToUpperCase(this IEnumerable<string> source)
    {
        foreach (string str in source)
        {
            Console.WriteLine("ToUpper: source >{0}<", str);
            yield return str.ToUpper();
        }
    }

    public static IEnumerable<string>
      AppendString(this IEnumerable<string> source, string stringToAppend)
    {
        // the following statement materializes the source collection in a List<T>
        // before iterating through it
        foreach (string str in source.ToList())
        {
            Console.WriteLine("AppendString: source >{0}<", str);
            yield return str + stringToAppend;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        string[] stringArray = { "abc", "def", "ghi" };

        IEnumerable<string> q1 =
            from s in stringArray.ConvertCollectionToUpperCase()
            select s;

        IEnumerable<string> q2 =
            from s in q1.AppendString("!!!")
            select s;

        foreach (string str in q2)
        {
            Console.WriteLine("Main: str >{0}<", str);
            Console.WriteLine();
        }
    }
}

この例では、次の出力が生成されます。

ToUpper: source >abc<
ToUpper: source >def<
ToUpper: source >ghi<
AppendString: source >ABC<
Main: str >ABC!!!<

AppendString: source >DEF<
Main: str >DEF!!!<

AppendString: source >GHI<
Main: str >GHI!!!<

この例では、 ToList を呼び出すと、 AppendString が最初の項目を生成する前にソース全体を列挙することがわかります。 ソースが大きな配列の場合、アプリケーションのメモリ プロファイルが大幅に変更されます。

このチュートリアルの最後の記事に示すように、標準クエリ演算子を連結することもできます。

こちらも参照ください