使用对象初始化程序生成CA 2000警告 [英] using object initializer generates CA 2000 warning

查看:121
本文介绍了使用对象初始化程序生成CA 2000警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码生成一个CA2000警告:

Myclass myclass = null;
try
{
   myclass = new Myclass { Name = "a name" };
}
finally
{
   if (myclass != null)
   {
      myclass.Dispose();
   }
}

我发现了一些具有相同问题的主题,据我所知,问题是,编译器为构造函数生成了一个临时变量,对于该变量,我不调用Dispose().

var tmp = new MyClass();
tmp.Name = "a name";
myclass = tmp:

所以我的问题是,是否存在使用对象初始化程序的解决方案,而不会产生ca2000警告.

非常感谢.

正如Damien在注释中指出的,FxCop警告是有效的,因为C#编译器在隐藏的temp变量中创建了IDisposable实例,并且在初始化其中一个属性的过程中引发异常时,实例将不会被处置.

使用良好的API设计不会有问题,因为资源(实现IDisposable的事物)应包含Open(或BeginStart等)方法(根据框架设计)准则),并且在调用Open之前不应泄漏.创建此规则的原因与您遇到的原因相同:防止在初始化期间泄漏. FDG是在C#3.0之前编写的,但是当从该实例的构造函数中引发异常时,也会存在相同的问题(由于异步异常(例如线程异常中止),总是会发生此异常).由于此时尚未发布对实例的引用,因此任何人都无法处置该实例.因此,建议不要在构建过程中初始化基础资源.

因此,当Myclass包含某种Open方法时,并且不使用本身实现IDisposable的值对其进行初始化时,可以放心地删除该警告.在其他情况下,您应该还原为以下内容:

var myclass = new MyClass();

try
{
    myclass.Name = "a name";
}
finally
{
    myclass.Dispose();
}

Following code generates a CA2000 warning:

Myclass myclass = null;
try
{
   myclass = new Myclass { Name = "a name" };
}
finally
{
   if (myclass != null)
   {
      myclass.Dispose();
   }
}

i found some topics with the same problem and as I understand the problem is, that the compiler generates for the constructor a temporary variable and for this variable I'm not calling Dispose().

var tmp = new MyClass();
tmp.Name = "a name";
myclass = tmp:

so my question is, if there is a solution with using object initializer which not generates a ca2000 warning.

thanks in advanced.

解决方案

As Damien points out in the comments, the FxCop warning is valid, since the C# compiler creates the IDisposable instance in a hidden temp variable, and when an exception is thrown during the initialization of one of the properties that instance will not get disposed.

With a good API design this would not be a problem, since resources (things that implement IDisposable) should contain an Open (or Begin, Start, whatever) method (according to the Framework Design Guidelines), and should not leak before Open is called. This rule is created for the same reason as what you are experiencing: to prevent leaking during initialization. The FDG were written before C# 3.0, but the same problem exists when the an exception is thrown from within the constructor of that instance (which can always happen because of asynchronous exceptions such as thread aborts). Since the reference to the instance isn't published at that point, there is no way for anyone to dispose that instance. Initializing the underlying resources during construction is therefore not advised.

So you can safely discard that warning when Myclass contains some sort of Open method, and when you're not initializing it with values that implement IDisposable themselves. In other cases, you should revert to the following:

var myclass = new MyClass();

try
{
    myclass.Name = "a name";
}
finally
{
    myclass.Dispose();
}

这篇关于使用对象初始化程序生成CA 2000警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆