2011-07-31 52 views
3

我在我的项目上运行完整的代码分析,它说它有500个问题。我已经把它煮成了300个,但我正在为一个我似乎无法找到解决方案的问题而苦苦挣扎。在这种情况下解析代码分析“CA2000”规则?

规则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(游戏,控制字符串,布尔)',调用System.IDisposable.Dispose对象'新的ScreenspaceRectangle(游戏,Color.Black,Vector.Zero,Vector.Zero)'之前,所有引用超出范围。

我知道这个问题可以通过在创建对象周围使用“using”声明来正常解决,以确保它始终正确处置。但是在这种情况下我怎么解决它?

+1

为什么ScreenspaceRectangle需要放置? – 2011-07-31 06:52:55

回答

3

假设Window类是自定义类,你应该确保基类的构造函数存储ScreenspaceRectangle的参考,如果它需要它的构造函数外,它实现IDisposable并配置ScreenspaceRectangle的实例在Dispose方法。

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

1

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

这种方法的一个优点是它允许通过创建它们的代码处理嵌套IDisposables的清理,从而最小化对象创建和清理代码不同步的危险。一个警告是,必须使用线程静态字段来跟踪一次性管理器,或者将其传递给构造器链的每一步。前一种方法感觉很糟糕,但具有允许字段初始化器安全地创建IDisposable对象的优点。