1

据说IEnumerable用于自定义集合。用途之一是用于遍历自定义集合的 foreach 循环。

但是我的问题是,与其制作一个首先实现IEnumerable然后构造另一个类来实现IEnumerator来存储一组自定义对象的自定义集合,为什么我们不能只使用list<your_customer_object>.

提前感谢您的帮助。

4

9 回答 9

3

因为您可能想要实现不同的数据结构。IEnumerable抽象了序列的概念,而 aList有索引的概念,添加/删除项目及其自己的数据结构。

作为不同结构的示例,这是一个允许您进入无限foreach循环的类。

public class InfiniteSequence : IEnumerable<int>
{
    public IEnumerator<int> GetEnumerator()
    {
        return new InfiniteEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    class InfiniteEnumerator : IEnumerator<int>
    {
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public bool MoveNext()
        {
            Current++;
            return true;
        }

        public void Reset()
        {
            Current = 0;
        }

        public int Current { get; private set; }

        object IEnumerator.Current
        {
            get { return Current; }
        }
    }
}
于 2012-12-21T15:22:31.757 回答
1

当然你可以使用List<T>.

如果List<T>符合您的需要,请使用它并且不要创建继承自IEnumerable<T>.

于 2012-12-21T15:21:57.380 回答
1

您将提供自己的IEnumerable<T>何时List<T>不适合您的需求的实现。典型的例子是当你想支持你的集合的惰性求值时,可能使用一个使用yield return.

于 2012-12-21T15:23:31.460 回答
1

正如@ken2k 所说,您可以List<T>使用您的 T 类型获得 List 的通用版本。但是如果你想隐藏这个实现并自定义一些List<T>包含新特性的操作,你可以从 List 继承并实现你自己的方法。样品:

public class CustomerCollection : List<Customer> // at this time, you have all methods from List such as Add, Remove, [index] etc...
{
   public double AverageAge()
   {
       return this.Average(customer => customer.Age)
   }

   // other methods...
}

IEnumeralbe是 .Net Framework 中最抽象的集合,你可以在这个抽象中进行交互。

于 2012-12-21T15:33:22.517 回答
0

您可以只使用List<T>或任何其他通用集合类型。毕竟List<T>器物IEnumerable<T>

您是否有需要定制系列的特定边缘案例?

于 2012-12-21T15:22:12.577 回答
0

当然,您可以将您的成员定义为List<T>,但这会将您的类的客户绑定到特定的实现。如果您将成员定义为IEnumerable<T>(假设消费者只想枚举您的集合),那么您可以将实现更改为实现接口而不违反合同的不同集合类型。如果您将其更改List<T>SortedSet<T>执行订单,您的消费者不会受到影响。

这基本上是针对接口而不是具体类型进行编码的优势。

您可以使用不同的界面,即。ICollection<T>如果您的消费者想要的不仅仅是枚举。

于 2012-12-21T15:22:24.743 回答
0

如果它没有做任何其他事情,请继续。专门的收藏是为那些需要做……特别……事情的收藏而设计的。

(例如, aListViewItemCollection必须在更新时通知其父ListView级,因此它需要实现IList(T),因此IEnumerable(T)。如果您有一个自定义集合,它可能会继承自该集合。IEnumerable(T)仅当您的集合可以枚举时,仅继承 from 才有意义,但是未编入索引。)

于 2012-12-21T15:22:51.280 回答
0

你可以。

public class List<T> : IList<T>, ICollection<T>, 
IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, 
IEnumerable 
于 2012-12-21T15:23:34.463 回答
0

我认为这里混淆的根源是“自定义集合”和“自定义类实例的集合”之间的区别。在这两个中,您List<CustomObject>是后一种情况 - 您只是重用由其他人创建的集合并利用泛型来保留项目类型信息,仅此而已。真正的自定义集合可能会实现IEnumerable<T>,但您很少(如果有的话)需要它。

因此,在这种情况下,您不仅可以,而且可能还应该使用List<CustomObject>

于 2012-12-21T15:24:04.130 回答