CA2000 using a method using "use" but not using try / finally

I have a strange situation that I am trying to understand. This piece of code gives CA2000 (call Dispose on the object before all references ...):

var ms = new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml));
using(ms)
{
    var x = XamlReader.Load(ms);
    _defaultControlTemplate = x as ControlTemplate;
}

      

However, this other piece is not:

var ms = new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml));
try
{
    var x = XamlReader.Load(ms);
    _defaultControlTemplate = x as ControlTemplate;
}
finally { ms.Dispose(); }

      

According to Microsoft Documentation :

The using statement ensures that Dispose is called even if an exception is thrown when you call methods on the object. You can achieve the same result by placing an object inside a try block and then calling Dispose in the finally block ; in fact, this is how the using statement is translated by the compiler .

So I'm really lost here ... shouldn't these two statements be identical?

Update

Since people insist (without reading my comment) on the using

ettiquete explanation . I'll put it this way:

  using (var ms = new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml)))
  {
    var x = XamlReader.Load(ms);
    _defaultControlTemplate = x as ControlTemplate;
  }

      

This one still gives CA2000 on fxcop, so the original question remains.

Update 2

Adding some screenshots so you can see this Visual Studio 2010 and the whole feature.

First version (gives warning): With warning

Second version (ok): Correct build

+3


source to share


3 answers


(Removed some things that are not relevant to the question, and also some wrong things about ThreadAbortException

.)

You are likely experiencing a false positive reported by CA2000. You can search Microsoft Connect for CA2000 . There are quite a few problems (not all of them are false positives).



I have personally disabled CA2000 on some projects due to these false positives. I am using Visual Studio 2010 with code analysis and I just confirmed that yes, after having suppressed CA2000 for too long, we decided to disable it on the project I am currently working on.

+4


source


There is a difference in the two parts of the code, which might be the reason why FxCOP is placing one and not the other.

Please note that Code Analysis in Visual Studio 2010 Premium does not post any code snippet with this warning, so there may be some insight added over older versions of FxCOP.

Anyway, the difference is that the block used is not actually translated into the try / catch block mentioned in the question.



Here's the best translation:

var ms = new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml));
var temp = (IDisposable)ms;
try
{
    var x = XamlReader.Load(ms);
    _defaultControlTemplate = x as ControlTemplate;
}
finally
{
    if (temp != null)
        temp.Dispose();
}

      

Note that I am not saying that this is the cause of your warning, I am simply saying that there is one difference between the two pieces of code.

0


source


The correct code would be

using(var ms= new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml)))
{
    var x = XamlReader.Load(ms);
    _defaultControlTemplate = x as ControlTemplate;
}

      

You need to declare and assign inside a using statement. Then it will choose the utility correctly

Edit: Clarify the reference problem

I assume you are doing the following:

var ms;
using(ms= new MemoryStream(Encoding.Default.GetBytes(DefaultControlTemplateXaml)))
{
    var x = XamlReader.Load(ms);
    _defaultControlTemplate = x as ControlTemplate;
}

      

then you can still use the ms variable after deleting it. This is what it is about. Or perhaps you are assigning ms to another var inside a use block.

-1


source







All Articles