Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wenn Sie nicht vorsichtig sind, können Sie in einigen Situationen das Speicher- und Leistungsprofil Ihrer Anwendung drastisch ändern, indem Sie die vorzeitige Materialisierung von Sammlungen in Ihren Abfragen verursachen. Einige Standardabfrageoperatoren verursachen die Materialisierung ihrer Quellauflistung, bevor ein einzelnes Element zurückgegeben wird. Beispielsweise Enumerable.OrderBy durchläuft zuerst die gesamte Quellauflistung, sortiert dann alle Elemente, und schließlich wird das erste Element zurückgegeben. Dies bedeutet, dass es teuer ist, das erste Element einer sortierten Sammlung zu erhalten; Danach ist jedes Element nicht teuer. Das macht Sinn; Es wäre unmöglich, dass dieser Abfrageoperator andernfalls vorgehen kann.
Beispiel: Hinzufügen einer Methode, die aufruft ToList, wodurch Materialisierung verursacht wird
In diesem Beispiel wird das Beispiel in Chain-Abfragen (C#) geändert: Die AppendString Methode wird so geändert, dass sie ToList aufruft, bevor sie die Quelle durchläuft, was zu Materialisierung führt.
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();
}
}
}
Dieses Beispiel erzeugt die folgende Ausgabe:
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!!!<
In diesem Beispiel führt der Aufruf von ToList dazu, dass AppendString seine gesamte Quelle auflistet, bevor es das erste Element ausgibt. Wenn die Quelle ein großes Array wäre, würde dies das Speicherprofil der Anwendung erheblich ändern.
Standardabfrageoperatoren können auch miteinander verkettet werden, wie im letzten Artikel in diesem Lernprogramm gezeigt: