CA2000上的方法使用“使用”,但不使用try / finally

时间:2012-03-16 13:22:30

标签: c# .net code-analysis fxcop

我有一种奇怪的情况,我正在努力理解。这段代码给出了CA2000 (在所有引用之前调用对象上的Dispose ......)

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

但是,另一件不是:

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

根据Microsoft's documentation

  

using语句确保即使在对象上调用方法时发生异常,也会调用Dispose。 您可以通过将对象放在try块中然后在finally块中调用Dispose来实现相同的结果;实际上,这就是编译器翻译using语句的方式

所以我真的迷失在这里...这两个陈述是不是应该相同?

更新

因为人们坚持(不读我的评论)解释using ettiquete。我会这样说的:

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

这个仍然在fxcop上提供CA2000,所以最初的问题仍然存在。

更新2

添加一些屏幕截图,以便您可以看到这是Visual Studio 2010和整个功能。

第一个版本(发出警告): With warning

第二个版本(ok): Correct build

3 个答案:

答案 0 :(得分:4)

(删除了一些不适用于该问题的内容以及一些关于ThreadAbortException的错误内容。)

您可能正在经历CA2000报告的误报。您可以搜索Microsoft Connect for CA2000。存在相当多的问题(并非所有问题都是假阳性错误)。

由于这些误报,我个人已经在某些项目中关闭了CA2000。我正在使用带有代码分析的Visual Studio 2010,我刚刚验证了,是的,在不得不多次压制CA2000之后,我们决定在我正在进行的项目中将其关闭。

答案 1 :(得分:0)

这两段代码有所不同,这可能是为什么FxCOP标记一个但不标记另一个的原因。

请注意,Visual Studio 2010 Premium中的代码分析不会使用该警告标记任何一段代码,因此与旧的FxCOP版本相比,可能会增加一些理解。

无论如何,不​​同之处在于,实际上,使用块不会转换为问题中显示的try / catch块。

这是一个更好的翻译:

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();
}

请注意,我并不是说 是您警告的原因,我只是说这两段代码之间存在差异。

答案 2 :(得分:-1)

正确的代码是

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

您需要在using语句中声明和赋值。然后,它将正确调用dispose

编辑:澄清参考问题

我假设您执行以下操作:

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

然后你可以在处理后使用ms变量。这就是消息的意义所在。或者您可以将ms分配给using块中的另一个var。