什么是 .net 中的 IEnumerable
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3014737/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
what is IEnumerable in .net
提问by qnatestu1
what is IEnumerable in .net?
.net 中的 IEnumerable 是什么?
回答by Joel Coehoorn
It's ... something... that you can loop over. That might be a List or an Array or (almost) anything else that supports a foreachloop. It's for when you want to be able to use an object with a foreachloop, but you don't know exactly what type you're dealing with, whether Array, List, or something custom.
这是...东西...你可以循环。这可能是一个列表或数组或(几乎)任何其他支持foreach循环的东西。它适用于您希望能够使用带有foreach循环的对象,但您不确切知道要处理的类型是 Array、List 还是自定义类型。
So that's the first advantage there: if your methods accept an IEnumerable rather than an array or list they become more powerful because you can pass more different kinds of objects to them.
所以这是第一个优势:如果您的方法接受 IEnumerable 而不是数组或列表,它们会变得更强大,因为您可以将更多不同类型的对象传递给它们。
Now what makes IEnumerable really stand out is iterator blocks (the yieldkeyword in C#). Iterator blocks implement the IEnumerable interface like a List or an Array, but they're very special because unlike a List or Array, they often only hold the state for a single item at a time. So if you want to loop over the lines in a very large file, for example, you can write an iterator block to handle the file input. Then you'll never have more than one line of the file in memory at a time, and if you finish the loop earlier (perhaps it was a search and you found what you needed) you might not need to read the whole file. Or if you're reading the results from a large SQL query you can limit your memory use to a single record.
现在让 IEnumerable 真正脱颖而出的是迭代器块(yieldC# 中的关键字)。迭代器块像 List 或 Array 一样实现 IEnumerable 接口,但它们非常特殊,因为与 List 或 Array 不同,它们通常一次只保存单个项目的状态。因此,例如,如果您想遍历一个非常大的文件中的行,您可以编写一个迭代器块来处理文件输入。那么你永远不会在内存中一次有超过一行的文件,如果你早点完成循环(也许这是一次搜索并且你找到了你需要的东西),你可能不需要读取整个文件。或者,如果您正在读取大型 SQL 查询的结果,您可以将内存使用限制为单个记录。
Another feature is that this evaluation is lazy, so if you're doing complicated work to evaluate the enumerable as you read from it, that work doesn't happen until it's asked for. This is extra beneficial, because often (say, for searches again) you'll find you might not need to do the work at all.
另一个特点是这个评估是惰性的,所以如果你正在做复杂的工作来评估你读取的可枚举,那么在被要求之前,这项工作不会发生。这是额外的好处,因为通常(例如,再次搜索)您会发现您可能根本不需要做这项工作。
You can think of IEnumerable as if it were a just-in-time List.
您可以将 IEnumerable 视为一个即时列表。
回答by Justin Niessner
It's an interface implemented by Collection types in .NET that provide the Iterator pattern. There also the generic version which is IEnumerable<T>.
它是由 .NET 中的 Collection 类型实现的接口,提供Iterator 模式。还有通用版本是IEnumerable<T>.
The syntax (which you rarely see because there are prettier ways to do it) for moving through a collection that implements IEnumerable is:
在实现 IEnumerable 的集合中移动的语法(你很少看到,因为有更漂亮的方法来做到这一点)是:
IEnumerator enumerator = collection.GetEnumerator();
while(enumerator.MoveNext())
{
object obj = enumerator.Current;
// work with the object
}
Which is functionaly equivalent to:
这在功能上等同于:
foreach(object obj in collection)
{
// work with the object
}
If the collection supports indexers, you could also iterate over it with the classic for loop method but the Iterator pattern provides some nice extras like the ability to add synchronization for threading.
如果集合支持索引器,您也可以使用经典的 for 循环方法对其进行迭代,但迭代器模式提供了一些不错的附加功能,例如为线程添加同步的能力。
回答by David Basarab
First it is an interface. The definition according to MSDNis
首先它是一个接口。根据MSDN的定义是
Exposes the enumerator, which supports a simple iteration over a non-generic collection.
公开枚举器,它支持对非泛型集合的简单迭代。
Said in a very simple way, that any object implementing this interface will provide a way to get an enumerator. An enumerator is used with the foreachas one example.
以一种非常简单的方式说,任何实现此接口的对象都将提供一种获取枚举器的方法。一个枚举器与foreach作为一个例子一起使用。
A List implements the IEnumerable interface.
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);
}
The foreach looks cleaner.
foreach 看起来更干净。
回答by SWeko
The short answer is that it's anything you can use a foreachon.
简短的回答是,它是您可以使用的任何东西foreach。
回答by Seyedraouf Modarresi
It is a base interface that enables us to loop or iterate over an Collection.
The most important note about IEnumerable is that when you go through an object or collection it just holds the state of a single item at a time.
It has a good performance when you are iterating through big objects or collections because it does not load the entire object to memory in order to make iteration. for instance, suppose you decided to read a large file line by line and doing something on that, therefore you can write your own ReaderEnumrableto read your file with high performance.
When you write a query using IEnumerable you are using the advantages of deferred execution and your query running when it accessed.
Each time you run you iterate through a collection, a different collection created. For example in the following code each time the
listOfFilesaccessed theListOfAllFilesexecute again.public static void Main() { var listOfFiles = ListOfAllFiles(); var filesCount = listOfFiles.Count(); var filesAny = listOfFiles.Any(); var fileIterate = listOfFiles.Select(x => x.FullName); } private static IEnumerable<FileInfo> ListOfAllFiles() { foreach(var file in Directory.EnumerateFiles(Environment.CurrentDirectory)) { yield return new FileInfo(file); } }
它是一个基本接口,使我们能够循环或迭代集合。
关于 IEnumerable 最重要的一点是,当你浏览一个对象或集合时,它一次只保存一个项目的状态。
当您遍历大对象或集合时,它具有良好的性能,因为它不会将整个对象加载到内存中以进行迭代。例如,假设您决定逐行读取一个大文件并对其进行处理,因此您可以编写自己的ReaderEnumrable以高性能读取您的文件。
当您使用 IEnumerable 编写查询时,您将利用延迟执行的优势,并且您的查询在访问时运行。
每次运行时都会迭代一个集合,创建一个不同的集合。例如在下面的代码中,每次
listOfFiles访问都会ListOfAllFiles再次执行。public static void Main() { var listOfFiles = ListOfAllFiles(); var filesCount = listOfFiles.Count(); var filesAny = listOfFiles.Any(); var fileIterate = listOfFiles.Select(x => x.FullName); } private static IEnumerable<FileInfo> ListOfAllFiles() { foreach(var file in Directory.EnumerateFiles(Environment.CurrentDirectory)) { yield return new FileInfo(file); } }

