tags:

views:

125

answers:

4

Returning a method value from inside a using statement that gets a DataContext seems to always work fine, like this:

public static Transaction GetMostRecentTransaction(int singleId)
{
    using (var db = new DataClasses1DataContext())
    {
        var transaction = (from t in db.Transactions
                              orderby t.WhenCreated descending
                              where t.Id == singleId
                              select t).SingleOrDefault();
        return transaction;
    }
}

But I always feel like I should be closing something before I break out of the using brackets, e.g. by defining transaction before the using statement, get it's value inside the brackets, and then returning after the brackets.

Would defining and returning the variable outside the using brackets be better practice or conserve resources in any way?

+4  A: 

No, I think it's clearer this way. Don't worry, Dispose will still be called "on the way out" - and only after the return value is fully evaluated. If an exception is thrown at any point (including evaluating the return value) Dispose will still be called too.

While you certainly could take the longer route, it's two extra lines that just add cruft and extra context to keep track of (mentally). In fact, you don't really need the extra local variable - although it can be handy in terms of debugging. You could just have:

public static Transaction GetMostRecentTransaction(int singleId)
{
    using (var db = new DataClasses1DataContext())
    {
        return (from t in db.Transactions
                orderby t.WhenCreated descending
                where t.Id == singleId
                select t).SingleOrDefault();
    }
}

Indeed, I might even be tempted to use dot notation, and put the Where condition within the SingleOrDefault:

public static Transaction GetMostRecentTransaction(int singleId)
{
    using (var db = new DataClasses1DataContext())
    {
        return db.Transactions.OrderByDescending(t => t.WhenCreated)
                              .SingleOrDefault(t => t.Id == singleId);
    }
}
Jon Skeet
Sine it's you @jon, is it still safe if an exception gets thrown inside the using block?
David Archer
yes. using is simply syntactic sugar for a try/finally construct
Mitch Wheat
@Mitch, thanks :-)
David Archer
@David: As Mitch says, it's fine - I've updated the answer to make that clearer :)
Jon Skeet
Why use OrderByDescending in combination with SingleOrDefault?
erikkallen
@erikkallen: LINQ doesn't have a "MaxBy", unfortunately - so you can't get the row with the maximal value. For LINQ to Objects you can write your own fairly easily, but I'm not sure of a better way of doing it in this case. What would you suggest instead?
Jon Skeet
+5  A: 

Have a look at this

Understanding the 'using' statement in C#

The CLR converts your code into MSIL. And the using statement gets translated into a try and finally block. This is how the using statement is represented in IL. A using statement is translated into three parts: acquisition, usage, and disposal. The resource is first acquired, then the usage is enclosed in a try statement with a finally clause. The object then gets disposed in the finally clause.

astander
An interesting insight. Thanks.
Kangkan
That translates the question to: Any side effects of returning from the try-block of a try-finally?
Henk Holterman
No, the finally will always be called. http://www.techinterviews.com/interview-questions-for-c-developers
astander
+2  A: 

There are no side effects of returning from inside a using() statement.

Whether it makes the most readable code is another discussion.

Mitch Wheat
A: 

I think, it's all the same. There's nothing bad in the code. The .NET framework wouldn't care where the object is created. The thing that matters is whether it is referenced or not.

Kerido