在.NET中,IEnumerable是什么?有什么解释?
在.NET中,IEnumerable是什么?有什么解释?
这是一个可以循环遍历的东西。它可以是List、Array或者(几乎)任何其他支持foreach循环的东西。当你想要使用一个对象与foreach循环一起使用,但你不知道你正在处理的确切类型时,就可以使用它。可能是数组、列表或者自定义的其它东西。
那么这里的第一个优点是:如果你的方法接受IEnumerable而不是数组或列表,它们会变得更加强大,因为你可以将更多不同类型的对象传递给它们。
现在让IEnumerable真正脱颖而出的是迭代器块(C#中的yield关键字)。迭代器块像List或Array一样实现IEnumerable接口,但它们非常特殊,因为与List或Array不同,它们通常只保存单个项的状态。例如,如果你想循环遍历一个非常大的文件中的行,你可以编写一个迭代器块来处理文件输入。然后你永远不会一次在内存中保存超过一行的文件,并且如果你更早地完成循环(也许它是一个搜索,你找到了需要的东西),你可能不需要读取整个文件。或者如果你正在从大型SQL查询中读取结果,你可以将内存使用限制为一个记录。
另一个特点是,这个评估是“惰性”的,因此如果你在读取时执行复杂的工作来评估可枚举对象,那么该工作直到被要求才会发生。这是非常有利的,因为通常(例如,对于搜索)你会发现你可能根本不需要进行这项工作。
你可以将IEnumerable视为即时List。
IEnumarable
的关键在于,支持集合在特定扩展时才被枚举,无论是通过 foreach 还是索引器访问器。不幸的是,IEnumarable 似乎被盲目地用作最低接口,这现在会导致异步数据操作出现问题(例如,在垃圾回收上下文中执行 SQL)。我认为 ICollection
是你所说的除了“惰性评估”之外的所有内容,我们应该使用它,特别是如果数据已经被枚举过一次! - Piotr Kula在.NET中,集合类型实现了一个接口,提供迭代器模式。还有一种泛型版本,即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循环方法来迭代它,但迭代器模式提供了一些额外的好处,比如能够为线程添加同步。
object obj;
在 while 循环外声明,这会改变循环与捕获变量(如匿名函数)一起使用时的行为。 - Scott Chamberlain首先它是一个接口。根据MSDN的定义:
公开枚举器,支持对非泛型集合进行简单迭代。
简单来说,任何实现此接口的对象将提供一种获取枚举器的方法。例如可以使用枚举器与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
中使用的所有内容。IEnumerable <==> foreach
。 - SWeko它是一种基本接口,使我们能够循环或迭代集合。
关于 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);
}
}
IEnumerable
时,您正在使用yield return
,因此它们是完全相关的。 - Seyedraouf Modarresi