Hacker News new | ask | show | jobs
by noblethrasher 5287 days ago
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.
[1] Relevant source: http://pastebin.com/LwHD8MHc

[2] https://github.com/noblethrasher/Prelude/blob/master/SQL.cs

1 comments

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.