Bug in the File.ReadLines(..) method of the .net framework 4.0

后端 未结 7 1442
渐次进展
渐次进展 2021-01-11 16:31

This code :

IEnumerable lines = File.ReadLines(\"file path\");
foreach (var line in lines)
{
    Console.WriteLine(line); 
}
foreach (var line          


        
7条回答
  •  盖世英雄少女心
    2021-01-11 16:38

    I believe you are confusing an IQueryable with an IEnumerable. Yes, it's true that IQueryable can be treated as an IEnumerable, but they are not exactly the same thing. An IQueryable queries each time it's used, while an IEnumerable has no such implied reuse.

    A Linq Query returns an IQueryable. ReadLines returns an IEnumerable.

    There's a subtle distinction here because of the way an Enumerator is created. An IQueryable creates an IEnumerator when you call GetEnumerator() on it (which is done automatically by foreach). ReadLines() creates the IEnumerator when the ReadLines() function is called. As such, when you reuse an IQueryable, it creates a new IEnumerator when you reuse it, but since the ReadLines() creates the IEnumerator (and not an IQueryable), the only way to get a new IEnumerator is to call ReadLines() again.

    In other words, you should only be able to expect to reuse an IQueryable, not an IEnumerator.

    EDIT:

    On further reflection (no pun intended) I think my initial response was a bit too simplistic. If IEnumerable was not reusable, you couldn't do something like this:

    List li = new List() {1, 2, 3, 4};
    
    IEnumerable iei = li;
    
    foreach (var i in iei) { Console.WriteLine(i); }
    foreach (var i in iei) { Console.WriteLine(i); }
    

    Clearly, one would not expect the second foreach to fail.

    The problem, as is so often the case with these kinds of abstractions, is that not everything fits perfectly. For example, Streams are typically one-way, but for network use they had to be adapted to work bi-directionally.

    In this case, an IEnumerable was originally envisioned to be a reusable feature, but it has since been adapted to be so generic that reusability is not a guarantee or even should be expected. Witness the explosion of various libraries that use IEnumerables in non-reusable ways, such as Jeffery Richters PowerThreading library.

    I simply don't think we can assume IEnumerables are reusable in all cases anymore.

提交回复
热议问题