foreach循环如何在C#中工作?

哪些类可以使用foreach循环?

实际上, 严格来说,所有你需要使用foreach是一个公共的GetEnumerator()方法返回一个bool MoveNext()方法和一个? Current {get;} ? Current {get;}属性。 然而,这最常见的含义是“实现IEnumerable / IEnumerable<T> ,返回IEnumerator / IEnumerator<T>

暗示,这包括实现ICollection / ICollection<T>任何东西,比如Collection<T>List<T> ,arrays( T[] )等等。所以任何标准的“数据集合”通常都支持foreach

为了certificate第一点,下面的工作很好:

 using System; class Foo { public int Current { get; private set; } private int step; public bool MoveNext() { if (step >= 5) return false; Current = step++; return true; } } class Bar { public Foo GetEnumerator() { return new Foo(); } } static class Program { static void Main() { Bar bar = new Bar(); foreach (int item in bar) { Console.WriteLine(item); } } } 

它是如何工作的?

foreach(int i in obj) {...}这样的foreach循环foreach(int i in obj) {...}相当于:

 var tmp = obj.GetEnumerator(); int i; // up to C# 4.0 while(tmp.MoveNext()) { int i; // C# 5.0 i = tmp.Current; {...} // your code } 

但是,有一些变化。 例如,枚举器(tmp)支持IDisposable ,它也被使用(类似于using )。

请注意 ,循环内部 (C#5.0)与外部 (C#4.0)之间的声明“ int i ”的位置不同 。 如果你在你的代码块中使用匿名方法/ lambda,这很重要。 但那是另一回事;

来自MSDN :

foreach语句为数组或对象集合每个元素重复一组embedded式语句。 foreach语句用于遍历集合以获取所需信息,但不应该用于更改集合的内容以避免不可预知的副作用。 (重点是我的)

所以,如果你有一个数组,你可以使用foreach语句遍历数组,如下所示:

  int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 }; foreach (int i in fibarray) { System.Console.WriteLine(i); } 

你也可以用它遍历一个List<T>集合,如下所示:

 List<string> list = new List<string>(); foreach (string item in list) { Console.WriteLine(item); } 

根据博客文章Duck Notation ,使用鸭子打字。

这里的文档: 主要文章 与集合对象的 数组

请注意,“收集元素的types必须可以转换为标识符types”。 有时不能在编译时检查,如果实例types不可分配给引用types,则可能会生成运行时exception。

如果果篮中存在非Apple,如橙色,则会生成运行时exception。

 List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() }; foreach(Apple a in fruitBasket) 

这安全地将列表过滤到仅使用Enumerable.OfType的Apples

 foreach(Apple a in fruitBasket.OfType<Apple>() ) 
 IList<ListItem> illi = new List<ListItem>(); ListItem li = null; foreach (HroCategory value in listddlsubcategory) { listddlsubcategoryext = server.getObjectListByColumn(typeof(HroCategory), "Parentid", value.Id); li = new ListItem(); li.Text = value.Description; li.Value = value.Id.ToString(); illi.Add(li); IList<ListItem> newilli = new List<ListItem>(); newilli = SubCatagoryFunction(listddlsubcategoryext, "-->"); foreach (ListItem c in newilli) { illi.Add(c); } }