在调用方法或枚举响应时枚举 IEnumerable

本文关键字:枚举 响应 IEnumerable 调用 方法 | 更新日期: 2023-09-27 18:34:44

我想知道天气 当我调用方法或枚举方法的返回时,枚举方法的 IEnumerable 参数,假设我们有以下代码:

IEnumerable<T> ProcessList(IEnumerable<T> list)
{
    foreach(var element in list)
    {
        yield return ProcessElement(element);
    }
}

我最好奇的是如何编写类似扩展的Where-Linq。

在调用方法或枚举响应时枚举 IEnumerable

当枚举 ProcessList (enum2 ( 的结果时,才会枚举list (enumerable(:

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 项,因此它只会对这 10 项运行 ProcessElement() 方法。其余的只有在您使用它们时才会进行评估。