.net中的IEnumerable是什么?
Answers:
这是……您可以循环播放的东西。那可能是一个List或一个Array或(几乎)其他任何支持foreach
循环的东西。它用于您希望能够使用带有foreach
循环的对象,但又不知道要处理的类型是数组,列表还是自定义类型。
这就是那里的第一个优点:如果您的方法接受IEnumerable而不是数组或列表,则它们将变得更强大,因为您可以向它们传递更多不同类型的对象。
现在,使IEnumerable真正脱颖而出的是迭代器块(yield
C#中的关键字)。迭代器块像列表或数组一样实现IEnumerable接口,但它们非常特殊,因为与列表或数组不同,它们通常一次只保存单个项目的状态。因此,例如,如果要在一个非常大的文件中循环,可以编写一个迭代器块来处理文件输入。这样一来,您一次存储的文件就永远不会超过一行,而且如果您更早完成循环(也许是搜索并找到了所需的内容),则可能不需要读取整个文件。或者,如果您正在从大型SQL查询中读取结果,则可以将内存使用限制为一条记录。
另一个功能是此评估是惰性的,因此,如果您正在做复杂的工作来评估可读取的可枚举对象,那么直到需要它时,该工作才会发生。这是额外的好处,因为经常(例如,再次进行搜索)您可能会发现根本不需要进行这项工作。
您可以将IEnumerable视为即时列表。
IEnumarable
在于,not enumerated
直到特别扩展支持集合为止,无论是通过索引器进行的foreach还是访问器。不幸的是,IEnumarable似乎被盲目地用作了最低的接口,现在它导致异步数据操作(例如,在GarbageCollected上下文上执行SQL)的问题。我要说的ICollection
是,除了“惰性评估”外,您所说的都是每件事,我们应该使用它,特别是如果数据已经被枚举一次!
这是由.NET中的Collection类型实现的接口,该类型提供Iterator模式。也有通用版本IEnumerable<T>
。
在实现IEnumerable的集合中移动的语法(您很少看到,因为有做起来更漂亮的方法)是:
IEnumerator enumerator = collection.GetEnumerator();
while(enumerator.MoveNext())
{
object obj = enumerator.Current;
// work with the object
}
在功能上等效于:
foreach(object obj in collection)
{
// work with the object
}
如果该集合支持索引器,那么您也可以使用经典的for循环方法对其进行迭代,但是Iterator模式提供了一些不错的功能,例如为线程添加同步的功能。
object obj;
中,在循环之外声明了,这在处理捕获变量(如匿名函数)的事物时会改变循环的行为。
首先,它是一个接口。根据MSDN的定义是
公开枚举器,该枚举器支持对非泛型集合的简单迭代。
简单地说,实现此接口的任何对象都将提供一种获取枚举数的方法。一个枚举器用作foreach
示例。
列表实现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
on上使用它。
IEnumerable <==> foreach
它是一个基本接口,使我们可以循环或遍历Collection。
关于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);
}
}
yield return
时正在使用IEnumerable
,因此它们是完全相关的。