注意しないと、場合によっては、クエリでコレクションが早期に具体化され、アプリケーションのメモリとパフォーマンス プロファイルが大幅に変更される可能性があります。 一部の標準クエリ演算子では、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
が最初の項目を生成する前にソース全体を列挙することがわかります。 ソースが大きな配列の場合、アプリケーションのメモリ プロファイルが大幅に変更されます。
このチュートリアルの最後の記事に示すように、標準クエリ演算子を連結することもできます。
こちらも参照ください
GitHub で Microsoft と共同作業する
このコンテンツのソースは GitHub にあります。そこで、issue や pull request を作成および確認することもできます。 詳細については、共同作成者ガイドを参照してください。
.NET