gpt4 book ai didi

c# - 为什么要为命名迭代器返回 IEnumerable?

转载 作者:行者123 更新时间:2023-11-30 20:51:22 25 4
gpt4 key购买 nike

(C# 新手)有人能解释一下,为什么命名迭代器(我在 MS C# 编程指南中找到的术语)应该返回 IEnumerable

// Implementing the enumerable pattern
public System.Collections.IEnumerable SampleIterator(int start, int end)
{
for (int i = start; i <= end; i++)
{
yield return i;
}
}

类实现GetEnumerator()才有意义的 IEnumerableIEnumerable<T>接口(interface),但我不确定它为何以及如何适用于方法和属性。

编辑:有人指出我的问题提出得不好。(也许,我还在用C++思考)澄清:为了使用 foreach在某个类的对象上循环,类需要实现 IEnumerableIEnumerator接口(interface)或 yield return (即编译器负责一切)。示例:

class ListClass : System.Collections.IEnumerable
{
public System.Collections.IEnumerator GetEnumerator() {...//uses yield return }
....
}
....
ListClass listClass1 = new ListClass(); // class implements IEnumerable interface method
foreach (int i in listClass1) {...}

在上面的例子中,GetEnumerator()已实现,据我所知,如果您希望您的对象在 foreach 中运行,则必须实现环形。但是,当实现命名迭代器时(上面的代码),GetEnumerator()不是必需的,只有 IEnumberable<T> (或非泛型)必须由方法/属性返回。
希望这能澄清我的问题。

最佳答案

实际上,我会说它应该返回 IEnumerable<T> - 或 IEnumerable<int>在这种情况下。但原因是因为它有效,并且因为迭代器 block (具有 yield 语法的方法)可以为您实现该模式。如果你想做一些其他foreach 一起工作的事情, 你必须自己写 CustomEnumerable/CustomIterator ,并使用 MoveNext() 在迭代器中手动实现状态机/Current模式,记得把任何 finally等在 Dispose() .很多工作;收获不大。


编辑:这是一个写得不好的,可能有错误的实现,它是用困难的方式实现的,即手动返回自定义迭代器。请注意,返回 int[]List<int>会很简单,但显着改变了语义:它不再是假脱机迭代器,这就是 yield创建:

static CustomEnumerable SampleIteratorHard(int start, int end)
{
return new CustomEnumerable(start, end);
}
class CustomEnumerable
{
private readonly int start, end;
public CustomEnumerable(int start, int end)
{
this.start = start;
this.end = end;
}
public CustomIterator GetEnumerator()
{
return new CustomIterator(start, end);
}
}
class CustomIterator
{
private readonly int start, end;
int i, state, value;
public CustomIterator(int start, int end)
{
this.start = start;
this.end = end;
start = 0;
}
public bool MoveNext()
{
if (state == 2) return false;
if (state == 0)
{
i = start - 1; // to leave space for the ++
state = 1;
}
if (state == 1)
{
i++;
if (i <= end)
{
value = i;
return true;
}
}
state = 2;
return false;
}
public int Current { get { return value; } }
}

关于c# - 为什么要为命名迭代器返回 IEnumerable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21748467/

25 4 0