Mellanliggande materialisering (C#)
Om du inte är försiktig kan du i vissa situationer drastiskt ändra programmets minnes- och prestandaprofil genom att orsaka för tidig materialisering av samlingar i dina frågor. Vissa vanliga frågeoperatorer orsakar materialisering av källsamlingen innan de ger ett enda element. Till exempel Enumerable.OrderBy itererar först genom hela källsamlingen, sorterar sedan alla objekt och ger slutligen det första objektet. Det innebär att det är dyrt att få det första objektet i en ordnad samling. varje objekt är därefter inte dyrt. Detta är vettigt; det skulle vara omöjligt för frågeoperatorn att göra något annat.
Exempel: Lägg till en metod som anropar ToList
, vilket orsakar materialisering
Det här exemplet ändrar exemplet i Exempel på kedjefrågor (C#): AppendString
metoden ändras till anrop ToList innan den itererar via källan, vilket orsakar materialisering.
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();
}
}
}
Det här exemplet genererar följande utdata:
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!!!<
I det här exemplet kan du se att anropet gör AppendString
att ToList hela källan räknas upp innan det första objektet visas. Om källan var en stor matris skulle detta avsevärt ändra programmets minnesprofil.
Vanliga frågeoperatorer kan också länkas samman enligt den sista artikeln i den här självstudien: