what is IE开发者_运维问答numerable in .net?
It's ... something... that you can loop over. That might be a List or an Array or (almost) anything else that supports a foreach
loop. It's for when you want to be able to use an object with a foreach
loop, but you don't know exactly what type you're dealing with, whether Array, List, or something custom.
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.
Now what makes IEnumerable really stand out is iterator blocks (the yield
keyword 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.
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.
It's an interface implemented by Collection types in .NET that provide the Iterator pattern. There also the generic version which is 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:
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.
First it is an interface. The definition according to MSDN is
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 foreach
as one example.
A List implements the IEnumerable interface.
// 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.
The short answer is that it's anything you can use a foreach
on.
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 ReaderEnumrable to 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
listOfFiles
accessed theListOfAllFiles
execute 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); } }
精彩评论