4

好的,所以我只是在处理IEnumeratorand IEnumerable。现在 MSDN 说这些东西的主要目标是遍历客户集合。

很公平,但是我能够在不使用任何一个的情况下迭代自定义集合(或者至少我想这样认为)

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

所以我的理解有什么缺陷,上面给我的结果与我在实施IEnumeratorand后获得的结果相同IEnumerable

4

5 回答 5

18

但是,我能够在不使用任何一个的情况下遍历自定义集合

当然可以在没有接口的情况下迭代你自己的集合;如果你不能,那么你将如何实现接口?

作为代码实现者,不会为了方便而实现接口。您实现它是为了方便您的代码的使用者。该接口的意思是“注意客户:您可以枚举这个集合的内容,而不必知道我是如何实现它的”。

这就是接口的目的:它提供了一种抽象,允许您的代码的使用者使用它,而不必了解它是如何工作的。

于 2012-12-16T16:49:05.360 回答
2

在您的main函数中,您使用了两个方面person_list来遍历人员列表,Length以及[]在特定位置获取集合成员的运算符。

但是,如果您有一些容器或自定义集合没有实现其中一个或两个呢?例如,逐行读取文件的类可能事先不知道集合的长度是多少,因此无法定义Length。从队列中读取消息的枚举器可能只能获取下一个,而不是一个,例如,前四个位置[4]。在这两种情况下,您仍然可以正确地“迭代”集合。

IEnumerator并且IEnumerable只需要foreach工作所需的属性而不需要其他属性,这就是为什么函数可以将它们用作需求,因为它们知道它们将能够遍历它们传递的任何类型的集合。

于 2012-12-16T14:47:44.307 回答
1

您当然可以在不实现IEnumerable接口的情况下迭代自定义集合,但是迭代代码必须知道您的自定义集合。

如果您实现IEnumerable,则迭代所有元素的代码不需要知道您的person_list类。它使用某个实现的类的实例,如果将实际实例交换为稍后IEnumerable也实现的其他东西,它仍然可以工作。IEnumerable

于 2012-12-16T14:42:00.483 回答
1

实际上,在 C# 中,不需要实现IEnumerableIEnumerator自定义您自己的集合。如果您使用传统方式迭代集合,这对您来说很好,但是如果您使用foreach迭代集合就会很麻烦。

另一个原因,如果你想公开你的类以便 VB.NET 用户可以使用你应该考虑实现这两个接口。

请注意,IEnumerable非泛型和泛型集合的区别。非泛型一个属于System.Collection另一个属于System.Collection.Generic命名空间

于 2014-11-01T06:53:44.623 回答
0

有很多方法可以迭代自定义序列。一种方法是使用迭代器设计模式

迭代器模式用于统一遍历自定义序列(它可以是内存中的集合、生成的集合或其他东西)。在 .NET 世界中,这种模式以下列方式实现:我们有一个实现IEnumerable接口的可迭代对象(这向您的类的任何客户表明您有能力遍历您的内容)。

而且我们有一个迭代器本身(实现IEnumerator接口的对象),您可以将其视为指向可迭代对象中当前位置的“指针”。因为您可能有内部循环(即一次对同一对象进行多次迭代),所以您必须将可迭代对象从迭代器中分离出来。

基本上有很多方法可以遍历特定序列,但迭代器模式使您能够“概括”这种方法,将遍历算法的特定实现隐藏在实现内部的调用者中。

于 2012-12-19T20:52:20.267 回答