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

Naw*_*waz 48 c# generics ienumerable ilist icollection

IEnumerable和之间有什么区别IEnumerable<T>

我已经看到很多框架类实现了这两个接口,因此我想知道通过实现它们可以获得哪些优势?

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

public interface IEnumerable
{
    [DispId(-4)]
    IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,IEnumerable<T>源于IEnumerable,这意味着无论IEnumerable有什么,IEnumerable<T>继承,那么为什么我们实现两者而不仅仅是IEnumerable<T>?实施IEnumerable<T>还不够吗?

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

  • IListIList<T>
  • ICollectionICollection<T>

我也想知道这些.

Jon*_*eet 58

基本上,非通用接口首先出现在.NET 1.0和1.1中.然后,当.NET 2.0问世时,通用的等价物就出现了.如果泛型已经进入.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();
}
Run Code Online (Sandbox Code Playgroud)

另一方面,使用C#2(带有yield return等)中引入的迭代器块,幸运的是,你很少需要完全手工实现这些东西.您可能需要编写类似上面的内容,然后yield returnGetEnumerator方法中使用.

请注意,IList<T>不会延长IList,并且ICollection<T>不会延长ICollection.这是因为它的类型安全性较低......而任何泛型迭代器都可以被视为非泛型迭代器,因为任何值的(可能是装箱)转换object,IListICollection允许将值添加到集合中; 添加(比方说)一个字符串是没有意义的IList<int>.

编辑:我们需要的原因IEnumerable<T>是我们可以以类型安全的方式进行迭代,并传播这些信息.如果我IEnumerable<string>给你回复,你知道你可以放心地假设从它返回的所有内容都是字符串引用或null.有了IEnumerable,我们必须有效地(通常在一个foreach语句中隐式)转换从序列返回的每个元素,因为Current属性IEnumerator只是类型object.至于为什么我们仍然需要IEnumerable- 因为旧接口永远不会消失,基本上.使用它的现有代码太多了.

IEnumerable<T>没有扩展是可能的IEnumerable,但是任何想要使用的代码IEnumerable<T>都无法调用接受的方法IEnumerable- 而且.NET 1.1和1.0中有很多类似的方法.

  • 如果泛型已经进入.NET 1.0,那么生活本来会简单得多...... (15认同)
  • @Nawaz:主要是.基本上有很多代码使用它 - 你发布后不能真正删除公共接口. (3认同)

Edw*_*uck 7

一个返回Object类型的对象,另一个返回类型为T的对象.