为什么foreach语句接受实现“Collection”模式的对象而不是只接受实现IEnumerable的对象?

时间:2008-12-25 20:12:17

标签: c# foreach ienumerable

很多人问我为什么,而且我没有给他们一个好的答案。

显然有充分的理由。有谁知道吗?

我在这里搜索并找到了this question。它解释了它是如何工作的,但不是原因。

2 个答案:

答案 0 :(得分:11)

假设您想要等同于IEnumerable<int>,但使用的是C#1.0。你可以实现IEnumerable - 但这需要在每次迭代时装箱和拆箱。使用foreach的鸭子打字版本你可以在没有任何拳击的情况下逃脱。在许多情况下,拳击实际上并没有那么有害(我倾向于发现the performance hit is exaggerated),但它仍然不够优雅。

我强烈地,强烈怀疑如果在C#1.0中存在泛型,foreach将被限制为IEnumerable<T>

答案 1 :(得分:1)

鸭子类型的foreach与IEnumerable相比还有一些优势:

  1. 有些东西可以满足“IEnumerable”合约中可用的“foreach”,但不能完全满足合同,尤其是反复获得独立调查员的能力。关于这一点,同意“foreach”接受IEnumerator [通用或不通用]或IEnumerable [同样]将是一种替代解决方案。
  2. 虽然IEnumerable.GetEnumerator的某些实现返回一个实现IEnumerator的结构,虽然这在使用duck typing时很有用,但在某些情况下这种行为可能会有问题。 foreach使用duck typing这一事实允许编译器有一个公共的GetEnumerator()函数返回一个struct-type枚举器(它不实现任何接口)并让编译器使用它,同时让IEnumerable.GetEnumerator返回一个类。

第二个优势实际上只能通过鸭子打字来实现。