2014-01-31 100 views
0

foreach语句为阵列中的每个元素或实现接口System.Collections.IEnumerableSystem.Collections.Generic.IEnumerable<T>的对象集合重复一组嵌入式语句。foreach和IEnumerable之间有什么关系?

我知道如果我们想在对象集合上使用foreach,我们需要在它上面实现IEnumerable。

我想了解在IEnumerable中如何实现'foreach'的用法?

IEnumerable的源代码似乎只有一个函数'GetEnumerator',显然没有实现,因为IEnumerable是一个接口 - 那么foreach关键字如何实际使用IEnumerable接口进行枚举?

编辑: 也在试图理解它在这方面:

IEnumerable<Int> myNumbers = new IEnumerable<Int>(); 

其中的GetEnumerator()被调用/这里使用?

编辑2:

因此,答案似乎是:
1:鸭子类型 - (感谢@Alexei Levenkov我接受@horrorcat作为一个答案,因为我只能接受一种:))
(感谢@Gary Vass的)

+2

它只是调用这个方法。 – SLaks

+1

IEnumerable的实现者实现了GetEnumerator()方法,foreach调用这个方法,然后使用生成的IEnumerator遍历元素。 – Lukazoid

+0

也许你应该阅读[接口(C#编程指南)](http://msdn.microsoft.com/en-us/library/ms173156.aspx) –

回答

1

IEnumerable.GetEnumerator()返回枚举器对象(实现IEnumerator)。它有一个返回当前项目的属性“Current”和一个方法“MoveNext()”,它将枚举器推进到下一个项目。

这是执行foreach所需的所有foreach循环。它只是将“Current”属性赋值给一个变量,然后每次执行.MoveNext()。

通常,当您在类上实现IEnumerable时,您知道源是从哪里来的。所以,如果你有一类像这样

​​8

的IEnumerable的实施将看起来像这样

public class MyEnumerable : IEnumerable<string> 
{ 
    private List<string> items; 

    public IEnumerator<string> GetEnumerator() 
    { 
     return items.GetEnumerator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return items.GetEnumerator(); 
    } 
} 

注意,枚举从列表对象来,所以你不必担心创建一个枚举器(虽然你可以如果你需要通过实现IEnumerator)

+0

谢谢,这很有道理。 现在,如果我使用的IEnumerable这样的: 的IEnumerable SEL = someFunctionWhichReturnsAnIenumerable()(或LINQ语句) 随后的foreach不具备的GetEnumerator的实现,对不对? (因为IEnumerable源代码只有Getenumerator的空 定义,而不是实现。那么它在哪里得到GetEnumerator实现,它返回IEnumerator的 ? – Gadam

1

foreach电话IEnumerable.GetEnumerator()(如果集合实现一个)或容貌 - 2.我在试图创建一个接口的具体实例(在我的问题的第二部分)作出的明显错误为GetEnumerator()返回01的方法。

使用GetEnumerator()调用的结果迭代元素,将每个元素转换为在第一个参数foreach中指定的类型。

+0

如果'收集不执行'会发生什么? – Gadam

+0

@Gadam - 链接的答案包含详细信息 - 它使用鸭子键入在这种情况下找到必要的方法。 –

0

作为Lukazoid说:“IEnumerable的实现者实现GetEnumerator()方法,foreach调用此方法,然后使用生成的IEnumerator迭代元素“。

foreach只使用接口IEnumerable/IEnumerable <>,我认为这是一个C#捷径,用于编写'readonly'for循环,您可以使用该数据但不能编辑它。

还我发现这一点,在这里计算器//which may make this question a dup

What's going on behind the scene of the 'foreach' loop?

0

的foreach只是sytactic糖,以使使用IEnumerable的类型。像代码:

foreach (var item in collection) 
{ 
    ... 
} 

是由编译器转换为类似:

using (var enumerator = collection.GetEnumerator()) 
{ 
    while (enumerator.MoveNext()) 
    { 
     var item = enumerator.Current; 
     // loop contents here 
    } 
} 
相关问题