简体   繁体   English

为什么我们需要IEnumerator和IEnumerable?

[英]Why do we need IEnumerator and IEnumerable?

Ok so I was just working through the IEnumerator and IEnumerable . 好的,我只是在处理IEnumeratorIEnumerable 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 . 那么在我的理解中有什么缺陷,上面给出了我在实现IEnumeratorIEnumerable后获得的相同结果。

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. IEnumeratorIEnumerable完全需要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#中,不需要实现IEnumerableIEnumerator来自定义您自己的集合。 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.

相关问题 我真的需要实现IEnumerable吗? 什么是System.Collections.IEnumerator? - Do I REALLY need to implement IEnumerable? What is System.Collections.IEnumerator? 以下为什么不工作? (IEnumerable / IEnumerator) - Why doesn't the following work? (IEnumerable/ IEnumerator) 为什么我在实现IEnumerator的类中需要IEnumerator.Current <T> ? - Why do I need IEnumerator.Current in a class implementing IEnumerator<T>? 为什么IEnumerable <T> 有IEnumerator时需要 <T> ? - Why is IEnumerable<T> necessary when there is IEnumerator<T>? 为什么在实现IEnumerable时需要实现IEnumerator - Why is it necessary to implement IEnumerator when Implementing IEnumerable 为什么接口 IEnumerable 返回 IEnumerator GetEnumemrator()? 为什么不只实现接口 IEnumerator? - Why does interface IEnumerable return IEnumerator GetEnumemrator()? Why not just implement interface IEnumerator? 为什么我们需要 IEnumerable<string> 在获取方法之前?</string> - Why we need IEnumerable<string> before get method? 将IEnumerable <T>转换为IEnumerator <T>的做法是什么 - What does casting an IEnumerable<T> to IEnumerator<T> do 在ICollection中实现IEnumerator和IEnumerable - implement IEnumerator and IEnumerable in ICollection 收益率回报== IEnumerable和IEnumerator? - Is Yield Return == IEnumerable & IEnumerator?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM