![](/img/trans.png)
[英]What is the difference between ((IEnumerable)source).OfType<T>() and source as IEnumerable<T>
[英]Difference between IEnumerable and IEnumerable<T>?
IEnumerable
和IEnumerable<T>
什么区别?
我已经看到很多框架类实现了这两个接口,因此我想知道通过实现它们可以获得哪些优势?
请看看他们是如何定义的:
public interface IEnumerable
{
[DispId(-4)]
IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
正如我们所看到的, IEnumerable<T>
派生自IEnumerable
,这意味着无论IEnumerable
有什么, IEnumerable<T>
继承,那么为什么我们实现两者而不仅仅是IEnumerable<T>
? 实现IEnumerable<T>
还不够吗?
同样,还有其他类似的对:
IList
和IList<T>
ICollection
和ICollection<T>
我也想知道这些。
基本上,非通用接口首先出现在.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();
}
另一方面,使用C#2中引入的迭代器块(具有yield return
等),幸运的是,您很少需要完全手动实现这些东西。 您可能需要编写类似上面的内容,然后在GetEnumerator
方法中使用yield return
。
需要注意的是IList<T>
不延伸IList
,和ICollection<T>
不延伸ICollection
。 这是因为它的类型安全性较低......而任何泛型迭代器都可以被视为非泛型迭代器,因为任何值都可以(可能是装箱)转换为object
, IList
和ICollection
允许将值添加到集合中; 将一个字符串添加到IList<int>
是没有意义的。
编辑:我们需要IEnumerable<T>
的原因是我们可以以类型安全的方式进行迭代,并传播该信息。 如果我向你返回一个IEnumerable<string>
,你知道你可以放心地假设从它返回的所有东西都是一个字符串引用或null。 使用IEnumerable
,我们必须有效地(通常隐式地在foreach
语句中)转换从序列返回的每个元素,因为IEnumerator
的Current
属性只是object
类型。 至于为什么我们仍然需要IEnumerable
- 因为旧的接口永远不会消失,基本上。 使用它的现有代码太多了。
IEnumerable<T>
可能不会扩展IEnumerable
,但是任何想要使用IEnumerable<T>
都无法调用接受IEnumerable
的方法 - 并且有很多类似的方法。 NET 1.1和1.0。
一个返回Object类型的对象,另一个返回类型为T的对象。
至于为什么你看到定义两者的类,尽管IEnumerable <T>实现了IEnumerable,但它不是必需的,但是在自我文档中有时列出子接口是很好的。 考虑
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则不会。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.