无法理解 IEnumerator
我目前正在学习 C#,以便有效地使用 Razor 和 Umbraco,我有一点 PHP 背景和 JavaScript 的合理知识。
我遇到了 IEnumerator 界面,但很难理解它。我在下面设置了一个代码片段来演示使用 foreach 循环遍历数组:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace cardEnum
{
class suitsEnumerator
{
private static string[] suits = { "Hearts", "Spades", "Diamonds", "Clubs" };
public void showAll()
{
foreach(string x in suits){
System.Console.WriteLine(x);
}
}
}
class run
{
static void Main()
{
Console.WriteLine("The suits are:");
var suits = new suitsEnumerator();
suits.showAll();
Console.ReadKey();
}
}
}
有人可以解释为什么我什至需要使用 IEnumerator
,否则我可以很容易地循环遍历数组。我知道这是一个非常简单的问题,我只是想不出使用 IEnumerable 的理由。
任何帮助将不胜感激,谢谢!
I'm currently learing C# for the purpose of effectivly usingRazor and Umbraco, I have a little bit of background in PHP and a reasonable knowledge in JavaScript.
I came across the IEnumerator
interface and have had difficulty getting my head around it. I've setup a code snippet below to demonstrate looping through an array with foreach:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace cardEnum
{
class suitsEnumerator
{
private static string[] suits = { "Hearts", "Spades", "Diamonds", "Clubs" };
public void showAll()
{
foreach(string x in suits){
System.Console.WriteLine(x);
}
}
}
class run
{
static void Main()
{
Console.WriteLine("The suits are:");
var suits = new suitsEnumerator();
suits.showAll();
Console.ReadKey();
}
}
}
Can someone explain why I would even need to use IEnumerator
when I can quite easily loop through the array otherwise. I KNOW this is such a simple question, I just cant think of an reason to use IEnumerable.
Any help at all would be greatly appreciated, thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这就是在您的示例中实现枚举器模式的方式。我希望这能澄清一些事情,特别是
IEnumerable
和IEnumerator
之间的关系:当然,这是一个为了帮助理解而设计的示例。由于
string[]
已经实现了IEnumerable
,因此没有理由重新发明轮子。由于 C# 支持
yields
关键字,因此创建 Enumerator 最近变得更加容易:This is how the enumerator pattern could be implemented in your example. I hope this clarifies a few things, in particular, the relationship between
IEnumerable
andIEnumerator
:Of course, this is a contrived example to aid understanding. Since
string[]
already implementsIEnumerable
, there's no reason to reinvent the wheel.Since C# supports the
yields
keyword, creating an Enumerator got a little easier recently:首先,如果您要创建自己的枚举器,则应该使该类实现 IEnumerator 接口(或其通用等效接口)。
通常,枚举器用于在集合中一次移动一项。这是一个简单的界面,用于支持移动项目,但不代表项目本身。它只有当前项目和移动到下一个项目的概念。
另一方面,IEnumerable 旨在表示项目的集合。根据其定义,IEnumerable 返回一个枚举器,其目的是枚举 IEnumerable 集合中的每个项目。它们不是相互排斥的类,而是依赖类。
您通常不会像示例中那样创建一个枚举器来遍历您的值。您将创建一个集合并使用枚举器对其进行导航(或者在更高级别迭代在幕后使用枚举器的集合)。
First of all, if you are going to create your own enumerator, you should make the class implement the IEnumerator interface (or its generic equivalent).
Typically enumerators are used to move, one item at a time, through a collection. It's a simple interface for supporting the moving items, but not representing the items themselves. It only has the concept of the current item and moving to the next.
IEnumerable, on the other hand, is intended to represent the collection of items. IEnumerable, by its definition, returns an enumerator whose purpose is to enumerate through each item in the IEnumerable collection. They are not mutually exclusive classes, the are dependent classes.
You wouldn't normally create an enumerator to go through your values like in your example. You would create a collection and use an enumerator to navigate it (or at a higher level iterate the collection which uses an enumerator behind the scenes).
您可能(而且经常)必须执行一些比仅仅打印对象的值更复杂的操作。
您的类可能必须一一返回(产生)对象以进行某些外部处理(通过某些其他类、方法等)。
那么暴露一个
IEnumerator
比返回整个集合更好,因为枚举意味着您一次只传递一个对象!不是一次(可能)一百万个元素的数组。You may (and often will) have to to perform some more complex operations than just printing out the values of your objects.
Your class could have to return (yield) objects one by one for some external processing (by some other class, method etc.).
Then exposing an
IEnumerator
is better than returning an entire collection, because enumerating means you're only passing one object at the time! Not an array of (possibly) one milion elements at once.C# 编译器对此进行了转换:
使用
IEnumerator
(或IEnumerator
)。IEnumerable
和 < code>IEnumerableGetEnumerator
方法,该方法返回一个IEnumerator
(或分别是IEnumerator
),这就是您使用foreach
进行的迭代所使用的内容。例外是使用数组完成的迭代,编译器以不同的方式对待它(感谢@Jon Skeet)。
The C# compiler transforms this:
To use
IEnumerator
(orIEnumerator<T>
).The
IEnumerable
andIEnumerable<T>
interfaces define aGetEnumerator
method that returns anIEnumerator
(orIEnumerator<T>
, respectively) which is what is being used for the iteration you are doing withforeach
.The exception is iteration done with arrays, which the compiler treats differently (thanks @Jon Skeet).
这很好,因为你的代码依赖于接口(
IEnumerable
)今天,如果你决定使用 for 循环,你的代码中的套装类型是数组,
你的代码看起来或多或少像下面
这样明年你可能有一个理由将其类型从
Array
更改为List
。如果您使用 for ,则需要更新代码块,因为 Array 具有 Length 属性,而 List 具有 Count 属性。It's good because your code is depend on interface (
IEnumerable
)Today type of suits in your code is Array
if you decide to use for loop you code look more or less like below
Next year you may have a reason to change its type from
Array
toList<T>
. If you use for you need to update block of code since Array hasLength
while List hasCount
property.如果您查看 System.Array,您会发现 Array 实现了 IEnumerable。
并且每个都不需要 IEnumerable 对象。它只需要一个名为 GetEnumerator 的方法。
If you look at System.Array you'll see that Array implements IEnumerable.
And for each doesn't need an IEnumerable object. It only needs a method called GetEnumerator.
假设您要创建一个自定义套装集合...学习如何实现
IEnumerable
将使您深入了解它为何如此有用。没有它,LINQ 就不可能存在。Suppose you were to create a custom collection of suits ...learning how to implement the
IEnumerable<T>
will give you a bit of insight on why it is so useful. Without it, LINQ could not exist as we know it.