Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Если вы не будете осторожны и внимательны, то в некоторых ситуациях можете существенно изменить характеристики памяти и производительности вашего приложения, вызвав преждевременную материализацию коллекций в запросах. Некоторые стандартные операторы запросов вызывают материализацию исходной коллекции перед получением одного элемента. Например, 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 перебирает весь свой источник перед тем, как получить первый элемент. Если источник был большим массивом, это значительно изменит профиль памяти приложения.
Операторы стандартных запросов также можно объединить в цепочку, как показано в заключительной статье в этом руководстве: