C# CA2000在C中向基构造函数传递对象引用#

C# CA2000在C中向基构造函数传递对象引用#,c#,constructor,code-analysis,reliability,ca2000,C#,Constructor,Code Analysis,Reliability,Ca2000,当我通过VisualStudio的代码分析实用程序运行某些代码时,我收到一条警告,我不知道如何解决这些问题。也许有人在这里遇到了类似的问题,解决了它,并愿意分享他们的见解 我正在为DataGridView控件中使用的自定义绘制单元格编程。代码类似于: public class DataGridViewMyCustomColumn : DataGridViewColumn { public DataGridViewMyCustomColumn() : base(new DataGridVi

当我通过VisualStudio的代码分析实用程序运行某些代码时,我收到一条警告,我不知道如何解决这些问题。也许有人在这里遇到了类似的问题,解决了它,并愿意分享他们的见解

我正在为DataGridView控件中使用的自定义绘制单元格编程。代码类似于:

public class DataGridViewMyCustomColumn : DataGridViewColumn
{
    public DataGridViewMyCustomColumn() : base(new DataGridViewMyCustomCell())
    {
    }
它会生成以下警告:

CA2000:Microsoft。可靠性:在方法“DataGridViewMyCustomColumn.DataGridViewMyCustomColumn()”中,在对象“new DataGridViewMyCustomCell()”的所有引用都超出范围之前,对其调用System.IDisposable.Dispose

我知道这是在警告我DataGridViewMyCustomCell(或它继承自的类)实现IDisposable接口,并且应该调用Dispose()方法来清除DataGridViewMyCustomCell在不再使用时声明的任何资源

我在互联网上看到的示例建议使用using块来限定对象的生存期,并让系统自动处理它,但base在移动到构造函数体中时无法识别,因此我无法围绕它编写using块。。。我不确定我是否愿意这样做,因为这不会指示运行时释放对象,该对象以后仍可以在基类中使用吗


那么,我的问题是,代码是否正常?或者,如何重构它来解决警告?我不想压制这个警告,除非这样做确实合适

如果您使用的是Visual Studio 2010,那么CA2000将完全崩溃。FxCop的其他版本(也称为代码分析)也可能会破坏它,但VS2010是我唯一可以担保的版本。我们的代码库为这样的代码提供CA2000警告

internal static class ConnectionManager 
{
    public static SqlConnection CreateConnection()
    {
         return new SqlConnection("our connection string");
    }
}
…指示在连接超出方法中的作用域之前未对其进行处理。嗯,是的,这是真的,但它并没有超出应用程序的范围,因为它返回给调用方-这就是该方法的全部要点!同样,构造函数参数没有超出范围,而是传递给基类,因此这是规则的误判,而不是实际问题


这曾经是一个有用的规则,但现在你真正能做的就是关闭它,直到他们修复它。这是不幸的,因为(很少)实际的积极因素是应该纠正的。

没有安全而优雅的方法让链式构造函数将新的
IDisposable
对象传递给基础构造函数,正如您所注意到的,不可能在任何类型的
try finally
块中包装链式构造函数调用。有一种方法是安全的,但并不优雅:定义一种实用方法,如:

internal static TV storeAndReturn<TR,TV>(ref TR dest, TV value) where TV:TR
{ 
  dest = value; return value;
}
protected DataGridViewMyCustomColumn(ref IDisposable cleaner) : 
   base(storeAndReturn(ref cleaner, new DataGridViewMyCustomCell()))
{
}

需要新对象的代码必须调用公共静态工厂方法,该方法将调用try/最后块中的相应构造函数,该块的主线将在其完成之前清空cleaner,如果它不为空,则其
finally
块将调用
cleaner
上的
Dispose
。假设每个子类都定义了一个类似的工厂方法,这种方法将确保新的
IDisposable
对象即使在创建时和封装对象暴露给客户机代码时发生异常,也会得到处理。该模式很难看,但我不确定其他更好的模式是否能保证正确性。

+1表示“在VS10中完全崩溃”。当这些工具让我看起来如此愚蠢时,很难说服人们加入我的代码质量改进之旅。。。