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>还不够吗?
同样,还有其他类似的对:
IList 和 IList<T> ICollection 和 ICollection<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 return在GetEnumerator方法中使用.
请注意,IList<T>并不会延长IList,并且ICollection<T>也不会延长ICollection.这是因为它的类型安全性较低......而任何泛型迭代器都可以被视为非泛型迭代器,因为任何值的(可能是装箱)转换object,IList并ICollection允许将值添加到集合中; 添加(比方说)一个字符串是没有意义的IList<int>.
编辑:我们需要的原因IEnumerable<T>是我们可以以类型安全的方式进行迭代,并传播这些信息.如果我IEnumerable<string>给你回复,你知道你可以放心地假设从它返回的所有内容都是字符串引用或null.有了IEnumerable,我们必须有效地(通常在一个foreach语句中隐式)转换从序列返回的每个元素,因为Current属性IEnumerator只是类型object.至于为什么我们仍然需要IEnumerable- 因为旧接口永远不会消失,基本上.使用它的现有代码太多了.
IEnumerable<T>没有扩展是可能的IEnumerable,但是任何想要使用的代码IEnumerable<T>都无法调用接受的方法IEnumerable- 而且.NET 1.1和1.0中有很多类似的方法.