user240141
user240141

Reputation:

Is it a good approach to call return inside using {} statement?

I just want to know is it safe/ good approach to call return inside a using block.

For ex.

using(var scope = new TransactionScope())
{
  // my core logic
  return true; // if condition met else
  return false;
  scope.Complete();
}

We know the at the last most curly brace dispose() will get called off. But what will be in the above case, since return jumps the control out of the given scope (AFAIK)...

  1. Is my scope.Complete() get called?
  2. And so for the scope's dispose() method.

Upvotes: 120

Views: 49219

Answers (6)

Øyvind Bråthen
Øyvind Bråthen

Reputation: 60694

It's perfectly safe to call return inside your using block, since a using block is just a try/finally block.

In your example above after return true, the scope will get disposed and the value returned. return false, and scope.Complete() will not get called. Dispose however will be called regardless since it reside inside the finally block.

Your code is essentially the same as this (if that makes it easier to understand):

var scope = new TransactionScope())
try
{
  // my core logic
  return true; // if condition met else
  return false;
  scope.Complete();
}
finally
{
  if( scope != null) 
    ((IDisposable)scope).Dispose();
}

Please be aware that your transaction will never commit as there's no way to get to scope.Complete() to commit the transaction.

Upvotes: 168

daryal
daryal

Reputation: 14919

In the example you have provided, there is a problem; scope.Complete() is never called. Secondly, it is not a good practice to use return statement inside using statements. Refer to the following:

using(var scope = new TransactionScope())
{
    //have some logic here
    return scope;      
}

In this simple example, the point is that; the value of scope will be null when using statement is finished.

So it is better not to return inside using statements.

Upvotes: 1

Tony Kh
Tony Kh

Reputation: 1572

scope.Complete should definitely be called before return. Compiler will display a warning and this code will never be called.

Regarding return itself - yes, it is safe to call it inside using statement. Using is translated to try-finally block behind the scene and finally block is to be certainly executed.

Upvotes: 2

ThunderGr
ThunderGr

Reputation: 2367

In this example, scope.Complete() will never execute. However, the return command will cleanup everything that is assigned on the stack. The GC will take care of everything that is unreferenced. So, unless there is an object that can not be picked up by the GC, there is no problem.

Upvotes: 0

M. Mennan Kara
M. Mennan Kara

Reputation: 10222

In general, it is a good approach. But in your case, if you return before calling the scope.Complete(), it will just trash the TransactionScope. Depends to your design.

So, in this sample, Complete() is not called, and scope is disposed, assuming it is inheriting IDisposable interface.

Upvotes: 2

Lucero
Lucero

Reputation: 60190

That's fine - finally clauses (which is what the closing curly brace of the using clause does under the hood) always get executed when the scope is left, no matter how.

However, this is only true for statements that are in the finally block (which cannot be explicitly set when using using). Therefore, in your example, scope.Complete() would never get called (I expect the compiler to warn you about unreachable code though).

Upvotes: 7

Related Questions