What's hot ? (and I mean really ...) - scroll down for more
1).  Code Templating - advanced usage of delegates & generics: my slides & demos are available for download! CodeProject article is also available.

2).  My series "TDD in the eyes of a simpleminded" is in progress(including code!): preface, part1, part2, Q&A 1, Manual Stub .vs. Mock Stub

3).  TDD Workshop: SeeCompass v0.1 and v0.2 are out.
# Friday, May 05, 2006

The using keyword works on objects that implement IDisposable interface (an interface with one member, the Dispose() method).
So a code like this:

using (SqlConnection conn = new SqlConnection("connection_string"))
{
    // use conn...
}

Is actually transformed into:

SqlConnection conn = null;
try
{
    conn = new SqlConnection("connection_string");
}
finally
{
    if (conn!=null)
        conn.Dispose();
}

The using keyword allows more elegant writing, nothing more actually.

The additional feature I would like to see is that in case of exception, a method in the implementor of IDisposable will be called, meaning the code should(?) be transformed into something like this:

SqlConnection conn = null;
try
{
    conn = new SqlConnection("connection_string");
}
catch(Exception err) // *
{
    HandleException(err);
}
finally
{
    if (conn!=null)
        conn.Dispose();
}


Of course, I would have to implement HandleException(Exception e) method as part of implementing IDisposable interface.

Why is this good for ??

Well, think about creating a transaction scope interface:

interface ITransactionScope : IDisposable
{
    void Commit();
    void Rollback();
    // ....
}

In this scenario, it would be great that if no exceptions were thrown, the transaction should Commit() by default,
but if any exception was thrown and not handled - do Rollback().

using (ITransactionScope trans = DbServices.StartTransactionScope())
{

    // delete 1

} // should do Commit()


using (ITransactionScope trans = DbServices.StartTransactionScope())
{
    
    // delete 1
    
    throw new ArgumentException("just to make the point clear");

} // should do Rollback()


HandleException(Exception e) will allow me to set a flag for Rollback on Dispose or to Rollback immediately; This can be quite handy.

Today I Rollback at the Dispose(if the transaction state is "uncommitted") and I force my programmers to call Commit() method directly.

* I know that catching Exception is a bad practice by default, but in those scenarios I would rather ask the "is\as" question(s) and handle my exception than wrapping using with try-catch blocks. After all, using should allow elegant code...

What do you think ?

update:
I've posted a ladybug at Microsoft Product Feedback, you can check it out (and vote!!!) here:

http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=f3c7e216-8790-4937-acc0-502848232a9d

Friday, May 05, 2006 9:29:13 PM (Jerusalem Standard Time, UTC+02:00)
I posted something similar a while ago, the idea was to change IDisposable itself to add OnError() method.

I recommend that you will open a ladybug issue on the matter.
This is important
Friday, May 05, 2006 9:45:20 PM (Jerusalem Standard Time, UTC+02:00)
They can't add OnError(Exception e) method to IDisposable as it will break existing code. I think that the best option is to invent a new keyword. something like "flow" or "transact" which will work with ITransactional : IDisposable. C# 3 maybe ?
Comments are closed.