[英]Why do we need IEnumerator and IEnumerable?
Ok so I was just working through the IEnumerator
and IEnumerable
. 好的,我只是在处理
IEnumerator
和IEnumerable
。 Now the MSDN says that the main objective of these things is to iterate through a customer collection. 现在MSDN说这些东西的主要目标是遍历客户集合。
Fair enough I was however able to iterate through a custom collection without the use of either (or at least I'd like to think so) 很公平但我能够在不使用任何一个的情况下迭代自定义集合(或者至少我想这么认为)
namespace ienumerator
{
class person
{
public person(string first, string second)
{
fname = first;
lname = second;
}
public string fname { get; set; }
public string lname { get; set; }
}
class person_list
{
public person[] list;
public person_list(person[] per)
{
list = new person[per.Length];
for (int i = 0; i < per.Length; i++)
{
list[i] = per[i];
}
}
}
class Program
{
static void Main(string[] args)
{
person[] names = new person[3]
{
new person("some","one"),
new person("another","one"),
new person("sss","ssdad"),
};
person_list list_of_names = new person_list(names);
int i = 0;
while (i < list_of_names.list.Length)
{
Console.WriteLine(list_of_names.list[i].fname);
i++;
}
Console.Read();
}
}
}
So what is flawed in my understanding, the above is giving me the same result that I achieve after implementing IEnumerator
and IEnumerable
. 那么在我的理解中有什么缺陷,上面给出了我在实现
IEnumerator
和IEnumerable
后获得的相同结果。
I was however able to iterate through a custom collection without the use of either
然而,我可以在不使用任何一个的情况下迭代自定义集合
Of course you can iterate your own collection without the interface; 当然, 您可以在没有界面的情况下迭代自己的集合; if you couldn't, then how would you implement the interface?
如果你不能,那你将如何实现界面?
You, as a code implementor, do not implement an interface for your convenience. 作为代码实现者, 您不会为了方便而实现接口。 You implement it for the convenience of the consumer of your code.
您为了方便代码的使用者而实现它。 The interface means "attention customer: you can enumerate the contents of this collection without having to know anything about how I implemented it".
界面意味着“关注客户:您可以枚举此集合的内容,而无需了解我如何实现它”。
That's the purpose of an interface: it provides an abstraction that allows consumers of your code to use it without having to understand how it works. 这就是界面的目的:它提供了一种抽象,允许代码的消费者使用它而无需了解它的工作原理。
In your main
function you used two aspects of person_list
to iterate through the list of people, Length
and the []
operator for taking the member of a collection at a certain position. 在您的
main
函数中,您使用了person_list
两个方面来遍历人员列表, Length
和[]
运算符,用于将集合的成员person_list
某个位置。
However, what if you had some container or custom collection which didn't implement one or both of these? 但是,如果您有一些容器或自定义集合未实现其中一个或两个,该怎么办? For example, a class that read a file line by line might not know in advance what the length of the collection was and so not define
Length
. 例如,逐行读取文件的类可能事先不知道集合的长度是多少,因此不定义
Length
。 An enumerator that reads messages from a queue might only be able to take the next one, and not one, say, four positions ahead with [4]
. 从队列中读取消息的枚举器可能只能接受下一个,而不是一个,比如前面的四个位置
[4]
。 In both cases you can still 'iterate' through the collection properly. 在这两种情况下,您仍然可以正确地“迭代”整个集合。
IEnumerator
and IEnumerable
require exactly the attributes that are needed for foreach
to work and no others, which is why functions can use them as requirements, knowing that they will be able to iterate through whatever type of collection they get passed. IEnumerator
和IEnumerable
完全需要foreach
工作所需的属性而不需要其他属性,这就是为什么函数可以将它们用作需求,因为它们知道它们能够遍历它们传递的任何类型的集合。
You can of course iterate over a custom collection without implementing the IEnumerable
interface, but then the iterating code has to know your custom collection. 您当然可以迭代自定义集合而无需实现
IEnumerable
接口,但迭代代码必须知道您的自定义集合。
If you implement IEnumerable
, the code that iterates over all elements does not need to know your person_list
class. 如果实现
IEnumerable
,则迭代所有元素的代码不需要知道您的person_list
类。 It uses an instance of some class that implements IEnumerable
, and it will still work if you exchange the actual instance for something else that also implements IEnumerable
later on. 它使用一个实现
IEnumerable
类的实例,如果你将实际的实例交换为后来也实现IEnumerable
其他东西,它仍然可以工作。
Actually, in C#, it is not required to implement the IEnumerable
and IEnumerator
to customize you own collections. 实际上,在C#中,不需要实现
IEnumerable
和IEnumerator
来自定义您自己的集合。 If you iterate the collection by using traditional way that is fine for you, but it will be trouble if you use foreach
to iterate the collection. 如果您使用适合您的传统方式迭代集合,但如果您使用
foreach
迭代集合则会遇到麻烦。
Another reason, if you want to expose your class so that VB.NET user can employ you should consider to implement the both interface. 另一个原因,如果你想暴露你的类以便VB.NET用户可以使用你应该考虑实现这两个接口。
Be note that IEnumerable
is difference in non-generic and generic collection. 请注意,
IEnumerable
在非泛型和泛型集合中是不同的。 The non-generic one belong to System.Collection
the other is belong to System.Collection.Generic
namespace 非泛型属于
System.Collection
,另一个属于System.Collection.Generic
命名空间
There is a plenty of ways to iterate over custom sequence. 有很多方法可以迭代自定义序列。 One way to do this is to use Iterator Design Pattern .
一种方法是使用迭代器设计模式 。
Iterator Pattern is used to unify traversing over custom sequence (it could be a collection in memory, generated collection or something else). Iterator模式用于统一遍历自定义序列(它可以是内存中的集合,生成集合或其他内容)。 In .NET world this pattern implemented in the following way: we have a iterable object that implements
IEnumerable
interface (and this shows to any customer of your class that you have a ability for traversing your content). 在.NET世界中,这种模式以下列方式实现:我们有一个可迭代的对象,它实现了
IEnumerable
接口(这向你的班级的任何客户展示了你有能力遍历你的内容)。
And we have a iterator itself (object that implements IEnumerator
interface) that you can treat as a "pointer" to current position in your iterable object. 我们有一个迭代器本身(实现
IEnumerator
接口的对象),您可以将其视为可迭代对象中当前位置的“指针”。 Because you may have inner loops (ie multiple iterations over the same object in one time) you have to split iterable object from the iterator. 因为您可能有内部循环(即一次在同一个对象上进行多次迭代),您必须从迭代器中拆分可迭代对象。
Basically there is a plenty of ways to traverse a specific sequence, but Iterator Pattern gives you an ability to "generalize" this approach hiding particular implementation of the traversing algorithm from the callers inside the implementation. 基本上有很多方法可以遍历特定的序列,但是迭代器模式使您能够“概括”这种方法,从实现中的调用者隐藏遍历算法的特定实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.