"CA2000 Dispose objects before losing scope "原因不明



我已经查看了MSDN文档,并在此代码片段中采用了推荐的模式:

  BitmapSymbols temp = null;
  try {
    using (var source = bitmaps.Symbols) {
      temp = new BitmapSymbols(source, sizeSymbols);
    }
    _bitmapSymbols = temp;
    temp           = null;
  } finally { 
    if (temp!=null) temp.Dispose(); 
  }

有人知道为什么temp在这种情况下被报告吗?我看不到temp未被处置且未设置为"null"的任何执行路径。事先感谢您的帮助。

如果我将赋值从-and-to - temp移到using中,FxCop会生成相同的警告。

BitmapSymbols实现IDisposable,并且是几个位图集合的包装器,确保它们都在同一时间被处理。

更新:
问题在下面:

无论如何,我不明白你为什么要写这段代码,而不是简单地使用:
_bitmapSymbols = new BitmapSymbols(source, sizeSymbols);

原因是,如果发生异常,不遵循该模式可能会导致内存泄漏。我正在编写一款用户可能在不重新启动的情况下运行数小时或数天的游戏,所以避免内存泄漏对于稳定性非常重要。

我终于偶然发现了误报的原因(两个独立的案例),即使在MSDN文档中为CA2000在失去作用域推荐的模式:

  1. 如果临时可丢弃变量的名称不是所显示的确切模式,即在camelCase中预先添加到目的地可丢弃的字符串"temp",则将由于无法识别推荐的模式而生成误报。假阳性很容易通过更改名字来消除。

  2. 如果目标可丢弃变量是一个属性,而不是一个字段或局部,则模式无法识别。要消除这里的误报,需要编写一个像这样的一次性函数:

    void SomeMethod() {
      // :  
      HexgridPath   = SetGraphicsPath();
      // :
    }
    GraphicsPath SetGraphicsPath() {
      GraphicsPath path     = null;
      GraphicsPath tempPath = null;
      try {
        tempPath  = new GraphicsPath();
        tempPath.AddLines(new Point[] {
          new Point(GridSize.Width*1/3,                0), 
          new Point(GridSize.Width*3/3,                0),
          new Point(GridSize.Width*4/3,GridSize.Height/2),
          new Point(GridSize.Width*3/3,GridSize.Height  ),
          new Point(GridSize.Width*1/3,GridSize.Height  ),
          new Point(                 0,GridSize.Height/2),
          new Point(GridSize.Width*1/3,                0)
        } );
        path     = tempPath;
        tempPath = null;
      } finally { if(tempPath!=null) tempPath.Dispose(); }
      return path;
    }
    

第一种情况看起来像一个典型的"初级程序员的第一次任务-刚离开学校"的错误;

第二种情况可能更难解决,但很烦人。

希望其他遇到这些假阳性的人可以从这个分析中受益。从长远来看,小的代码更改比简单地禁用错误要好,以防初级程序员对补救措施进行"优化"。

我相信删除if (temp != null)会使警告消失。我认为FxCop不够聪明,无法检查条件执行路径。

无论如何,我不明白为什么你想出这个代码,而不是简单地使用_bitmapSymbols = new BitmapSymbols(source, sizeSymbols); ?

最新更新