Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it OK doing a return from inside using block

Tags:

c#

return

I am doing a code review, and have found alot of code with the following format:

public MyResponse MyMethod(string arg) {     using (Tracer myTracer = new Tracer(Constants.TraceLog))     {         MyResponse abc = new MyResponse();          // Some code          return abc;     } } 

When I run a code analysis I get a CA2000 warning Microsoft.Reliability

Should the code be rewritten as:

public MyResponse MyMethod(string arg) {    MyResponse abc = new MyResponse();     using (Tracer myTracer = new Tracer(Constants.TraceLog))    {        // Some code    }    return abc; } 

Or does it not matter?

Edit

The line on which it is reporting the warning is:

MyResponse abc = new MyResponse(); 

MyResponse is a standard Dataset.

The full error message is:

Warning 150 CA2000 : Microsoft.Reliability : In method 'xxxxx(Guid, Guid)', object 'MyResponse ' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'MyResponse ' before all references to it are out of scope.

like image 340
Shiraz Bhaiji Avatar asked Apr 06 '11 14:04

Shiraz Bhaiji


People also ask

Can you return in with block Python?

Yes, it acts like the finally block after a try block, i.e. it always executes (unless the python process terminates in an unusual way of course).

Can you return in using C#?

The return statement terminates the execution of the method in which it appears and returns control to the calling method. When the method is executed and returns a value, we can imagine that C# puts this value where the method has been called. The returned value can be used for any purpose from the calling method.

How can a function return a value in C#?

Return valuesIf the return type (the type listed before the method name) is not void , the method can return the value by using the return statement. A statement with the return keyword followed by a value that matches the return type will return that value to the method caller.


2 Answers

No, it doesn't matter.

The finally block that's implicitly generated by the using statement to handle disposal will execute no matter where you put the return.

Are you sure that the CA2000 relates to myTracer and not abc? I would guess that the warning is occurring because MyResponse implements IDisposable and you're not disposing abc before returning. (Either way, your suggested rewrite should make no difference to the warning.)

like image 178
LukeH Avatar answered Sep 20 '22 20:09

LukeH


Your rewrite will not fix that CA2000 warning, because the problem is not the Tracer object, but the MyResponse object.
The documentation states:

The following are some situations where the using statement is not enough to protect IDisposable objects and can cause CA2000 to occur.
Returning a disposable object requires that the object is constructed in a try/finally block outside a using block.

To fix the warning without messing with the stack trace of your exceptions (<- click, it's a link), use this code:

public MyResponse MyMethod(string arg) {    MyResponse tmpResponse = null;    MyResponse response = null;    try    {        tmpResponse = new MyResponse();         using (Tracer myTracer = new Tracer(Constants.TraceLog))        {            // Some code        }         response = tmpResponse;        tmpResponse = null;     }     finally     {         if(tmpResponse != null)             tmpResponse .Dispose();     }     return response; } 

Why? Please see the example in the linked documentation.

like image 21
Daniel Hilgarth Avatar answered Sep 19 '22 20:09

Daniel Hilgarth