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

我正在编程DataGridView控件中使用的自定义细胞。代码类似于:

public class DataGridViewMyCustomColumn : DataGridViewColumn
{
    public DataGridViewMyCustomColumn() : base(new DataGridViewMyCustomCell())
    {
    }

它产生以下警告:

CA2000:Microsoft.reliability:在方法中'dataGridViewMyCustomColumn.datagridViewMyCustomColumn()'call system.idisposable.dispose在对象'new DataGridViewMyCustomCell()上''''''new DataGridViewMyCustomCell()'在所有引用之前,所有参考都不在范围之外。

我知道这是在警告我dataGridViewMyCustomCell(或它继承的类)实现IDISPOSABLE接口,并且应调用Dispose()方法以清理DataGridViewMyCustomCell声明的任何资源,而当它不再是。

我在Internet上看到的示例建议使用一个块来探讨对象的寿命并使系统自动处置它,但是当移动到构造函数的正文中时,基本无法识别,因此我无法使用使用使用一个阻止它...我不确定我是否想做,因为这是否会指示运行时间来释放基本类内可以使用的对象?

那我的问题,代码还可以吗?或者,如何重构解决警告?我不想抑制警告,除非确实适合这样做。

有帮助吗?

解决方案

如果您使用的是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/finally 主线将无效的街区 cleaner 就在完成之前,谁 finally 块会打电话 Disposecleaner 如果不是零。只要每个子类都定义了类似的工厂方法,则此方法将确保新的 IDisposable 即使在创建时间与封装对象暴露于客户端代码的时间之间发生异常,对象也会被处置。模式很丑陋,但我不确定其他更好的模式是否会确保正确性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top