什么是.NET中的IEnumerable
什么是.NET中的IEnumerable?
这是……可以循环的东西 这可能是一个List或一个数组或(几乎)任何其他支持foreach
循环。 这是为了当你想能够使用一个foreach
循环的对象,但你不知道你究竟处理什么types,无论是数组,列表或自定义。
所以这是第一个优点:如果你的方法接受一个IEnumerable而不是一个数组或列表,它们变得更强大,因为你可以传递更多不同types的对象给它们。
现在让IEnumerable真正脱颖而出的是迭代器块(C#中的yield
关键字)。 迭代器块像List或Array一样实现IEnumerable接口,但是它们非常特殊,因为它们不像List或Array,一次只能保存一个项目的状态。 所以,如果你想循环遍历一个非常大的文件中的行,你可以写一个迭代器块来处理文件input。 那么你一次不会在内存中拥有多行文件,如果你先完成了这个循环(也许这是一个search,并且你find了你需要的),你可能不需要读整个文件。 或者,如果您正在阅读大型SQL查询的结果,则可以将您的内存使用限制为单个logging。
另一个特性是这个评估是懒惰的 ,所以如果你在从中读取评估枚举值时做了复杂的工作,那么这个工作就不会发生,直到被请求。 这是非常有益的,因为经常(比如再次search),你会发现你可能根本不需要做这项工作。
您可以将IEnumerable想象成即时清单。
这是一个由.NET中的集合types实现的接口,它提供了Iterator模式 。 还有IEnumerable<T>
的通用版本。
在实现IEnumerable的集合中移动的语法(您很less看到,因为有更漂亮的方法):
IEnumerator enumerator = collection.GetEnumerator(); while(enumerator.MoveNext()) { object obj = enumerator.Current; // work with the object }
其function相当于:
foreach(object obj in collection) { // work with the object }
如果集合支持索引器,也可以用经典的for循环方法迭代它,但是迭代器模式提供了一些很好的附加function,例如为线程添加同步function。
首先它是一个接口。 根据MSDN的定义是
公开枚举器,它支持对非generics集合的简单迭代。
以一种非常简单的方式说,任何实现这个接口的对象都将提供一种获取枚举器的方法。 举例来说,枚举器与foreach
一起使用。
一个List实现了IEnumerable接口。
// This is a collection that eventually we will use an Enumertor to loop through // rather than a typical index number if we used a for loop. List<string> dinosaurs = new List<string>(); dinosaurs.Add("Tyrannosaurus"); dinosaurs.Add("Amargasaurus"); dinosaurs.Add("Mamenchisaurus"); dinosaurs.Add("Deinonychus"); dinosaurs.Add("Compsognathus"); Console.WriteLine(); // HERE is where the Enumerator is gotten from the List<string> object foreach(string dinosaur in dinosaurs) { Console.WriteLine(dinosaur); } // You could do a for(int i = 0; i < dinosaurs.Count; i++) { string dinosaur = dinosaurs[i]; Console.WriteLine(dinosaur); }
该foreach看起来更干净。
简单的答案是,这是任何你可以使用foreach
。
using System.Collections; using static System.Console; namespace SimpleIterators { class X { static int i = 0; public int I { get { return i; } } public X() { WriteLine("X "+i++); } } class Program { public static IEnumerable ValueI(X[] tabl) { for (int i = 0; i < 10; i++) yield return tabl[i].I; } public static IEnumerable ListClass(X[] tabl) { for (int i = 0; i < 10; i++) yield return tabl[i] = new X(); } static void Main(string[] args) { X[] tabl = new X[10]; foreach (X x in ListClass(tabl)); foreach (int i in ValueI(tabl)) WriteLine("X " + i); WriteLine("X " + tabl[0].I); ReadKey(); } } }