c# - C# 是否会受益于枚举器种类之间的区别,例如 C++ 迭代器?

标签 c# c++ ienumerable iterator

我一直在思考IEnumerator.Reset() 方法。我在 MSDN 文档中读到它仅用于 COM 互操作。作为一名 C++ 程序员,它看起来像一个支持 ResetIEnumerator,我称之为 forward iterator。 , 而不支持 ResetIEnumerator 实际上是一个 input iterator .

所以我的问题的第一部分是,这种理解是否正确?

我的问题的第二部分是,如果在输入迭代器和前向迭代器(或“枚举器”,如果您愿意)之间有所区别,这对 C# 有什么好处吗?它不会有助于消除程序员之间的一些困惑,就像在这个 SO question about cloning iterators 中发现的那样吗? ?

编辑:对前向和输入迭代器的澄清。输入迭代器仅保证您只能枚举集合的成员(或来自生成器函数或输入流)一次。这正是 IEnumerator 在 C# 中的工作方式。是否可以枚举第二次,取决于是否支持Reset。前向迭代器没有此限制。您可以根据需要多次枚举成员。

一些 C# 程序员不理解为什么不能在多 channel 算法中可靠地使用 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,换言之支持多遍算法,那么每次迭代集合时都会有所不同。这将是不可取的,因为这将是令人惊讶的行为。这个例子有点假,但它确实发生在现实世界中(例如从文件流中读取)。

最佳答案

Reset是个大错误。我调用恶作剧 Reset .在我看来,反射(reflect)您在 .NET 类型系统中“前向迭代器”和“输入迭代器”之间的区别的正确方法是区分 IEnumerable<T>。和 IEnumerator<T> .

另见 this answer ,Microsoft 的 Eric Lippert(毫无疑问,以非官方身份,我的观点只是他的资历比我声称这是设计错误的资历更多)在评论中提出了类似的观点。另见 his awesome blog .

关于c# - C# 是否会受益于枚举器种类之间的区别,例如 C++ 迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1634934/

相关文章:

c# - 为什么在枚举对象上设置属性不起作用?

c# - 找不到 JobRunShell.cs

c# - 在没有第二个线程的帮助下异步执行代码?

c++ - CGAL:如何创建填充边界曲线的表面网格?

c++ - 二进制搜索程序无法识别边界?

c# - 如何根据预定义的序列对 IEnumerable 进行排序?

c# - C# 中的 MongoDB 复合条件

c++ - 一起使用 C++ 和脚本

asp.net-mvc-3 - MVC3 IEnumerable 模型找不到正确的编辑器模板

c# - 更快的枚举 : Leveraging Array Enumeration