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); } }
- 使用程序集中的Web应用程序版本号(ASP.NET / C#)
- 我应该从使用boost :: shared_ptr切换到std :: shared_ptr?
- '((void(*)())0x1000)();`是什么意思?
- 是否定义了有符号整数的按位运算的结果?
- C ++和OpenGLmatrix顺序之间的混淆(row-major vs column-major)
- 从2012年到2013年更新后无法加载文件或程序集“System.Web.Http 4.0.0”
- 如何在可撤销的asynchronous/等待处置TransactionScope?
- 我可以使用Dictionary <TKey,TValue>条目的集合初始值设定项吗?
- 获取std :: future的状态