using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.None))
{
Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
// Add some information to the file.
fs.Write(info, 0, info.Length);
}
I was about to put this down. Although, the C# world requires an IDisposable interface and implies that you're operating on a resource.
Ruby has similar concept when you open a file and pass in a block to operate on the File object.
I'm pretty sure the author is just excited about the language and failed to recognize that this pattern is everywhere in different programming languages.
Yes, it is homegrown[1]. I have quite a few little utilities that use (or abuse) iterators to get something like RAII in C# (I don't like relying on using/IDisposable and I especially don't like requiring it in my public types).
Another one that I use a lot [2]:
SqlCommandEx sql = "select * from person";
foreach (dynamic result in sql)
{
var full_name = result.first_name + " " + result.last_name;
DateTime dob = result.dob;
//do other stuff
} //connection automatically disposed.
I'm going to assume I missed something, because from what I'm reading:
1. You're avoiding IDisposable for reasons you don't explain and I fail to see
2. You replace it with an idiom which is supposed to do the same thing (except abusing iterators instead of using tools dedicated to that job) and which I don't believe works, as your connection will not (as far as I can see) be disposed of if there's an error in the foreach block. And the code you linked does not seem to use this "pattern" anywhere
Avoiding using/IDisposable is taste thing; I'm not saying that anyone else should do it.
If called from the `foreach` statement, the code in a finally block of an iterator is guaranteed to execute even if the loop exits early due to a `break` or exception. The compiler will also generate a call to Dispose() as well.
Also, it's not really an abuse. When dealing with an unmanaged resource, you're almost always either pulling a stream of data out or pushing a stream of data in. That's precisely the use case of IEnumerable and its dual, IObservable (SqlCommandEx is an example of IEnumerable and FileEx is a loose example of IObservable).
P.S. Now there might be a thus far undiscovered bug in my SqlCommandEx code to which I linked (e.g. the compiler only generates calls to Dispose() on IEnumerator<T> which might not work for dynamic types, I haven't checked) but it's possible to do what I described in principle.