枚举器,迭代器,IEnumerable - 有点困惑

时间:2011-04-06 23:25:38

标签: asp.net-mvc-2 iterator ienumerable enumerable

我已经多次阅读了 C#3.0 in a Nutshell 中的Iterators / Enumerators部分,但我仍然很难理解它。从他们的名字开始,我最初的想法是Iterator将迭代一组Enumerable对象。我是在正确的轨道上吗?如果是这样,那么常见的通用集合如List<T>? List是否在其某些操作期间创建/使用Iterator? T会自动枚举吗?有演员吗?一个人甚至与另一个人有什么关系吗?

在一个有点相关的说明中,在学习MVC的过程中,我见过这样的代码:

public Article GetArticle(int id)
{
    return _siteDB.Articles.SingleOrDefault(a => a.ArticleID == id);
}

public IEnumerable<Article> GetArticle(string title)
{
    return _siteDB.Articles.Where(a => a.Title.StartsWith(title)).AsEnumerable<Article>();
}

返回类型IEnumerable<T>给了我什么?


编辑:好的,我想我已经开始明白了。我对Iterators的困惑仍然存在。该书将它们描述为枚举器的 producer 。我没有看到yield return实际发生的地方。每个yield都会创建一个新的枚举器吗?

3 个答案:

答案 0 :(得分:2)

IEnumerable类型为您提供IEnumerable :) 它是一个接口定义方法 GetEnumerator(),它返回IEnumerator。您可以根据需要多次调用该方法,并始终获取IEnumerator的新实例。

IEnumerator具有属性 Current 和方法 MoveNext() Reset(),允许集合枚举。如果 MoveNext()的上一次调用返回true,则可以通过调用 MoveNext()并读取 Current 属性来完成枚举本身。

实施和使用的良好示例在文档中:http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx

答案 1 :(得分:1)

  

从他们的名字开始,我最初的想法是迭代器会迭代一组Enumerable对象。我是在正确的轨道上吗?如果是这样,那么常见的通用集合如List? List是否在其某些操作期间创建/使用Iterator?

iterator是一种实现返回IEnumerable<T>的方法的方法 - 它实际上是一个实现细节。您可以使用迭代器来实现它,而不必创建一些通过集合枚举的自定义类,编译器会为您完成艰苦的工作。

  

拥有IEnumerable的返回类型会给我什么?

这基本上允许你枚举类型。例如,第二种方法(我个人称之为GetArticles)将允许您编写:

foreach(var article in GetArticle(theTitle))
{
   // Do something with article
}

答案 2 :(得分:1)

让我们看看我是否可以回答这个问题。

因此List实现IEnumerable,而不是必须实现它的T,列表中的任何内容都可以使用forech或for循环进行迭代。如果你使用像List这样的通用列表,这意味着你拥有的是T的列表,其中T是你定义的对象类型,这意味着你不必抛出它,但另一方面你只能放该列表中相同类型的对象。

你在那里的代码可能意味着一系列的事情:

1 - 任何实现IEnumerable的变量都能保存GetArticle的结果, 例如:

List yourList = GetArticle("test");
Queue myQueue = GetArticle("test");

2 - 查询的实际处理将被延迟。例如,如果你在调用方法之后调用Count,那么当它实际执行/解决时就是这样。

3 - 由于数字2,如果您在代码建议的数据库中执行此操作,那么您的连接必须保持打开状态,直到您使用该列表为止,否则您将获得异常。

我想我已回答了这些问题。