我一直在想IEnumerator.Reset()
方法。我在MSDN文檔中看到,它只在那裏用於COM互操作。作爲一名C++程序員,它在我看來就像是一個IEnumerator
,它支持Reset
就是我所說的forward iterator,而不支持Reset
的IEnumerator
確實是input iterator。C#能否像C++迭代器那樣區分各種枚舉類型?
所以我的問題的第一部分是,這種理解是否正確?
我的問題的第二部分是,如果在輸入迭代器和前向迭代器(或者如果你喜歡的話,是「枚舉器」)之間做出區分,它會對C#有什麼好處嗎?它會不會幫助消除程序員之間的一些混淆,例如在SO question about cloning iterators中找到的那個?
編輯:澄清正向和輸入迭代器。輸入迭代器只保證您可以枚舉一次集合的成員(或來自生成器函數或輸入流)的成員。這正是IEnumerator在C#中的工作原理。是否可以第二次枚舉,取決於是否支持Reset
。前向迭代器不具有此限制。您可以隨時列舉所有成員。
一些C#程序員不會爲什麼不能在多通道算法中可靠地使用IEnumerator
。考慮以下情況:
void PrintContents(IEnumerator<int> xs)
{
while (iter.MoveNext())
Console.WriteLine(iter.Current);
iter.Reset();
while (iter.MoveNext())
Console.WriteLine(iter.Current);
}
如果我們在這方面呼籲PrintContents
,沒問題:
List<int> ys = new List<int>() { 1, 2, 3 }
PrintContents(ys.GetEnumerator());
但是看看下面:
IEnumerable<int> GenerateInts() {
System.Random rnd = new System.Random();
for (int i=0; i < 10; ++i)
yield return Rnd.Next();
}
PrintContents(GenerateInts());
如果IEnumerator
支持Reset
,在換言之,它支持多遍算法,然後每次迭代集合時都會有所不同。這將是不可取的,因爲這將是令人驚訝的行爲。這個例子有點僞造,但它確實發生在現實世界中(例如從文件流中讀取)。
我想你是指'IEnumerator.Reset',而不是'IEnumerable.Reset',對吧? –
2009-10-28 02:50:30
是的,謝謝!對於那個很抱歉。 – cdiggins 2009-10-28 03:04:08
有趣的問題。但也許你應該解釋一下C++ - 講一點,因爲很多C#程序員都會看到這一點。確切地說(特別是它們的單通道/多通道功能,這與這個問題真正相關)可能並不明顯,輸入迭代器和前向迭代器是什麼, – jalf 2009-10-28 09:57:45