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.
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).
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.
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.
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.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With