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

发布于 2024-10-30 17:24:08 字数 759 浏览 5 评论 0原文

我已经通读了《C# 3.0 in a Nutshell》的迭代器/枚举器部分多次,但我仍然很难掌握它。从它们的名字来看,我最初的想法是迭代器将迭代一组可枚举对象。我走在正确的轨道上吗?如果是这样,那么常见的泛型集合(例如 List)又如何呢? List 在其某些操作期间是否创建/使用迭代器? 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>();
}

What does getting a return type of IEnumerableGive me?


编辑:好的,我想我开始明白了。我的困惑仍然是迭代器。书中将他们描述为枚举器的生产者。我不知道 yield return 实际发生在哪里。每个yield都会创建一个新的枚举器吗?

I've read through the Iterators/Enumerators section of C# 3.0 in a Nutshell several times, but I'm still having a hard time grasping it. From their names, my initial thought is that an Iterator would iterate over a group of Enumerable objects. Am I on the right track? If so, then what about common generic collections, like a List<T>? Does List create/make use of an Iterator during some of its operations? Is T automatically Enumerable? Is there a cast? Does one even have anything to do with the other?

On a somewhat related note, while learning MVC, I've seen code like so:

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>();
}

What does having a return type of IEnumerable<T> give me?


EDIT: Okay, I think I'm beginning to get it. My confusion remains with Iterators. The book describes them as producers of Enumerators. I don't see where that actually happens with yield return. Does each yield create a new Enumerator?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

裸钻 2024-11-06 17:24:08

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

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

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

The type IEnumerable gives you IEnumerable :)
It is an interface defining method GetEnumerator(), which returns IEnumerator. You can call the method as many times as you like and you always obtain new instance of IEnumerator.

The IEnumerator have property Current and methods MoveNext() and Reset() allowing the collection enumeration. The enumeration itself can be done by calling MoveNext() and reading the Current property if previous call of MoveNext() returns true.

Good example of implementation and usage is in documentation: http://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx

撩人痒 2024-11-06 17:24:08

从他们的名字来看,我最初的想法是迭代器会迭代一组可枚举对象。我走在正确的轨道上吗?如果是这样,那么常见的泛型集合(例如列表)又如何呢? List 在其某些操作期间是否创建/使用迭代器?

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

返回类型为 IEnumerable 会给我带来什么?

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

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

From their names, my initial thought is that an Iterator would iterate over a group of Enumerable objects. Am I on the right track? If so, then what about common generic collections, like a List? Does List create/make use of an Iterator during some of its operations?

An iterator is a way to implement a method returning an IEnumerable<T> - it's really an implementation detail. Instead of having to create some custom class to enumerate through a collection, you can use an iterator to implement it, and the compiler does the hard work for you.

What does having a return type of IEnumerable give me?

This basically allows you to enumerate over the type. For example, the second method (which I would personally call GetArticles), would allow you to write:

foreach(var article in GetArticle(theTitle))
{
   // Do something with article
}
想念有你 2024-11-06 17:24:08

让我看看我能否回答这个问题。

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

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

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

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

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

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

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

Lets see if I can answer this.

So a List implements IEnumerable, and its not the T that has to implement it, anything in a list can be iterated, using a forech or for loop, for example. If you use a generic list like List, this means that what you have is a list of T where T is the object type defined by you, that means you don't have to cast it, but in the other hand you can only put objects of that same type in that list.

The code you have up there, can mean a series of thing:

1 - Any variable that implements IEnumerable will be able to hold the result of GetArticle,
Ex:

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

2 - The actual processing of the query will be delayed. If you call Count for example, after you call the method, thats when it actually get executed/resolved.

3 - Because of number 2, if you are doing that on a DB as the code suggests, then you connection has to remain open till the time where you make use of the list, otherwise you will get an exception.

I think I have answered the questions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文