【问题标题】:Resolving code analysis "CA2000" rule in this scenario?在这种情况下解决代码分析“CA2000”规则?
【发布时间】:2011-10-16 19:27:13
【问题描述】:

我正在对我的项目进行完整的代码分析,它说它有 500 个问题。我现在已经将它归结为 300,但我正在努力解决一个我似乎无法找到解决方案的问题。

规则CA2000 规定:

如果一次性对象在所有对它的引用都超出范围之前没有被显式释放,那么当垃圾收集器运行对象的终结器时,该对象将在某个不确定的时间被释放。因为可能会发生异常事件,阻止对象的终结器运行,所以应该显式地释放对象。

可以在上面链接的页面上找到有关该规则的更多信息。

规则失败的代码是这样的:

internal Window(Game game, Control parent, string title, bool visible)
    : base(game, parent, visible, new ScreenspaceRectangle(game, Color.Black, Vector.Zero, Vector.Zero))
{
}

描述是:

CA2000 : Microsoft.Reliability : 在方法 'Window.Window(Game, Control, string, bool)' 中,调用 System.IDisposable.Dispose 对象'new ScreenspaceRectangle(game, Color.Black, Vector.Zero, Vector。 Zero)' 在所有对它的引用都超出范围之前。

我知道这个问题可以通过在正在创建的对象周围使用“使用”语句来正常解决,以确保始终正确处理它。但是在这种情况下我该如何解决呢?

【问题讨论】:

  • 为什么需要释放 ScreenspaceRectangle?

标签: c# .net code-analysis idisposable


【解决方案1】:

假设 Window 类是您的自定义类,您应该确保基类构造函数存储 ScreenspaceRectangle 的引用,如果它在构造函数之外需要它并且它实现 IDisposable 并在Dispose 方法。

否则,请确保对象在基类构造函数中被释放。

【讨论】:

    【解决方案2】:

    c#/vb.net 的一个令人讨厌的限制是它们不允许将链式构造函数或字段初始值设定项包装在 try-catch 或 try-finally 块中。如果对象 Foo 的创建需要创建 Foo 将负责处理的其他一些 IDisposable 对象,那么如果 Foo 的构造函数、其子类型或其子类型抛出异常,则可能难以确保这些对象将被释放超类型。我所知道的最干净的处理方法是使用受保护的构造函数,包装在工厂方法中,该方法将创建一个“一次性管理器”实例并将其传递给构造函数链。任何会创建 IDisposable 的东西都应该将它添加到一次性管理器;如果构造函数抛出异常,disposables manager将删除所有已注册的disposables。

    这种方法的一个优点是它允许嵌套 IDisposable 的清理由创建它们的代码处理,从而最大限度地减少对象创建和清理代码不同步的危险。一个警告是,必须要么使用线程静态字段来跟踪一次性管理器,要么将其传递给构造函数链的每一步。前一种方法感觉很恶心,但具有允许字段初始化器安全地创建 IDisposable 对象的优点。

    【讨论】:

      猜你喜欢
      • 2012-04-25
      • 1970-01-01
      • 2019-11-09
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 2016-04-24
      • 1970-01-01
      • 2011-04-19
      相关资源
      最近更新 更多