Я хочу знать, что параметр IEnumerable для метода перечисляется при вызове метода или когда я перечисляю возврат метода, предполагая, что у нас есть следующий код:
IEnumerable<T> ProcessList(IEnumerable<T> list)
{
foreach(var element in list)
{
yield return ProcessElement(element);
}
}
Мне больше всего любопытно, как писать Where-Linq как расширения.
list
(enumerable
) enumerable
только после перечисления результата ProcessList
(enum2
):
static void Main(string[] args)
{
var enumerable = Enum1();
Console.WriteLine("Enum1 retrieved");
var enum2 = Enum2(enumerable);
Console.WriteLine("Enum2 called");
foreach (var e in enum2)
{
Console.WriteLine(e);
}
}
private static IEnumerable<string> Enum1()
{
Console.WriteLine("Enum1");
yield return "foo";
}
private static IEnumerable<string> Enum2(IEnumerable<string> enumerable)
{
Console.WriteLine("Enum2");
foreach (var s in enumerable)
{
yield return s;
}
}
дает:
Enum1 retrieved
Enum2 called
Enum2
Enum1
foo
Последние три строки печатаются только при вводе циклы foreach
.
Использование ключевого слова yield
означает, что этот фрагмент кода будет оцениваться только по мере необходимости, чтобы предоставить результаты, которые вы используете. Другими словами, это не приведет к оценке:
var processed = ProcessList(unprocessed);
Содержимое списка результатов не имеет значения, поэтому они еще не будут оцениваться. Однако, если вы это сделаете:
var processed = ProcessList(unprocessed).ToList();
это попросит его оценить IEnumerable
, который заставит его запустить ваш код. Аналогично, если вы это сделаете:
var processed = ProcessList(unprocessed);
foreach (var x in processed)
{
DoSomething(x);
}
он будет запускать ваш метод ProcessElement()
для каждого элемента по очереди. Для этого, если вы это сделаете:
var processed = ProcessList(unprocessed);
foreach (var x in processed.Take(10))
{
DoSomething(x);
}
потому что вы используете только первые 10 элементов списка результатов, для них будет выполняться только ваш метод ProcessElement()
. Остальные будут оцениваться только тогда, когда вы их используете.