When working with files in C#, I am conditioned to think about freeing the associated resources. Usually this is a using statement, unless its a one liner convenience method
like File.ReadAllLines, which will open and close the file for me.
.Net 4.0 has introduced the convenience method File.ReadLines. This returns an IEnumerable and is billed as a more efficient way to process a file – it avoids storing the entire file in memory. To do this I’m assuming there is some deferred execution logic in the enumerator.
Obviously since this method returns an IEnumerable, not and IDisposable, I can’t go with my gut reaction of a using statement.
My questions is:
With this in mind, are there any gotchas on resource deallocation with this method?
Does calling this method mean that the release of the associated file locks is non-deterministic?
IEnumerabledoesn’t inherit from IDisposable because typically, the class that implements it only gives you the promise of being enumerable, it hasn’t actually done anything yet that warrants disposal.However, when you enumerate over it, you first retrieve an
IEnumeratorby calling theIEnumerable.GetEnumeratormethod, and typically, the underlying object you get back does implementIDisposable.The way
foreachis implemented is similar to this:This way, if the object does indeed implement
IDisposable, it will be disposed of. ForFile.ReadLines, the file isn’t really opened until you start enumerating over it, so the object you get fromFile.ReadLinesdoesn’t need disposing, but the enumerator you get, does.As the comments indicate,
IEnumeratordoes not inherit fromIDisposable, even though many typical implementations does, whereas the genericIEnumerator<T>does inheritIDisposable.