IEnumerable和IEnumerable <T>之间的区别?

IEnumerableIEnumerable<T>什么区别?

我见过很多实现这两个接口的框架类,所以我想知道通过实现这两个接口有什么好处?

请看看他们是如何定义的:

 public interface IEnumerable { [DispId(-4)] IEnumerator GetEnumerator(); } public interface IEnumerable<T> : IEnumerable { IEnumerator<T> GetEnumerator(); } 

正如我们所看到的, IEnumerable<T>IEnumerable派生,这意味着无论IEnumerable具有什么, IEnumerable<T>inheritance,那么为什么我们要实现而不仅仅是IEnumerable<T>呢? 正在实现IEnumerable<T>不够?

同样,还有其他类似的配对:

  • IListIList<T>
  • ICollectionICollection<T>

我也想知道这些。

在.NET 1.0和1.1中基本上是非属性接口。 然后,当.NET 2.0出来,generics等价物出来了。 如果仿制药进入到.NET 1.0中,生活将会变得更简单:)

在实现“唯一”的IEnumerable<T>而不是两个 – 你基本上必须实现两个,你也必须使用显式接口实现,既定义了一个无参数的GetEnumerator方法。 由于IEnumerator<T>扩展IEnumerator ,所以通常是这样的:

 public IEnumerator<T> GetEnumerator() { // Return real iterator } // Explicit implementation of nongeneric interface IEnumerator IEnumerable.GetEnumerator() { // Delegate to the generic implementation return GetEnumerator(); } 

另一方面,使用C#2中引入的迭代器块(带有yield return等),你很less需要手工完成这些事情,幸运的是。 您可能需要编写类似上面的内容,然后在GetEnumerator方法中使用yield return

请注意, IList<T>不会扩展IList ,并且ICollection<T>不会扩展ICollection 。 这是因为这样做不是types安全的,而任何generics迭代器都可以被视为非generics迭代器,因为任何值(可能是装箱)转换为objectIListICollection允许将值添加到集合中; 将一个string添加(比如说)给IList<int>是没有意义的。

编辑:我们需要IEnumerable<T>的原因是,我们可以以types安全的方式迭代,并传播信息。 如果我向您返回一个IEnumerable<string> ,那么您知道可以安全地假设从它返回的所有内容都将是一个string引用或null。 使用IEnumerable ,我们必须有效地(通常隐含在foreach语句中)从序列返回的每个元素进行投射,因为IEnumeratorCurrent属性只是typesobject 。 至于为什么我们仍然需要IEnumerable – 因为旧的界面从来没有消失,基本上。 现有的代码太多了。

IEnumerable<T>可能不会扩展IEnumerable ,但是任何想要使用IEnumerable<T>都不能调用接受IEnumerable的方法 – 并且有很多这样的方法。 NET 1.1和1.0。

一个返回一个Objecttypes的对象,另一个返回一个Ttypes的对象。

至于为什么你看到类定义了两个,虽然IEnumerable <T>实现了IEnumerable,但它不是必须的,但在自我logging中有时会列出子接口。 考虑

 interface IA { } interface IB : IA { } class A : IB {} // legal, IB implements IA class B : IA, IB {} // also legal, possible more clear on intent 

在遍历循环时,IEnumerator维护状态。 它记得游标的位置,IEnumerable没有。