“CA2000 在失去范围之前处理对象”,原因不明
Posted
技术标签:
【中文标题】“CA2000 在失去范围之前处理对象”,原因不明【英文标题】:"CA2000 Dispose objects before losing scope " for unknown reason 【发布时间】:2013-06-19 22:09:06 【问题描述】:我查看了 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”的执行路径。提前感谢您的任何帮助。
如果我在 using 中将分配从 temp
移动到另一处,则会从 FxCop 生成相同的警告。
BitmapSymbols
类实现了IDisposable
,并且是多个位图集合的包装器,可确保它们都被同时释放。
更新: 问题提出如下:
无论如何,我不明白你为什么想出这段代码而不是简单地使用:
_bitmapSymbols = new BitmapSymbols(source, sizeSymbols);
原因是如果发生异常,不遵循模式可能会导致内存泄漏。我正在编写一个游戏,用户可能会运行数小时或数天而无需重新启动,因此避免内存泄漏对于稳定性很重要。
【问题讨论】:
temp
是否实现IDisposable
?
@DJKRAZE:是的,代码编译和运行都很好,所以temp
实现了IDisposabe
;这只是 FxCop 的抱怨,但我在其他几个地方使用了相同的模式,并且在其中一些地方得到了相同的 FxCop 警告。
为什么要在 using.. 之外设置 temp = null?
@DJKRAZE:没关系;我已经尝试了两种方法,并从 FxCop 中得到了相同的警告。你能看出为什么偏爱一个而不是另一个的原因吗?我不能。
如果你将 temp.Dispose
重写为 ((IDisposable)temp).Dispose();
如果它在编译时抱怨,那么只需将 temp 的值设置为 null
并继续
【参考方案1】:
我终于偶然发现了误报的原因(两个不同的案例),即使 MSDN 文档 here 中推荐的模式CA2000 Dispose Objects Before Losing Scope 紧随其后:
如果临时一次性变量的名称不是显示的确切模式,即在 camelCase 中附加到目标一次性变量的字符串“temp”,则会生成误报由于未能识别推荐的模式。更改名称很容易消除误报。
如果目标一次性变量是属性而不是字段或局部变量,则无法识别该模式。消除此处的误报需要编写一个一次性函数,如下所示:
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;
第一种情况看起来像是典型的“初级程序员的第一次作业-刚毕业”的错误;
第二种情况可能更难解决,但很烦人。
希望遇到这些误报的其他人可以从该分析中受益。从长远来看,小的代码更改比简单地禁用错误要好,以防初级程序员“优化”补救措施。
【讨论】:
【参考方案2】:我相信删除if (temp != null)
会使警告消失。 FxCop 不够聪明,无法检查我认为的条件执行路径。
无论如何,我不明白你为什么想出这段代码而不是简单地使用_bitmapSymbols = new BitmapSymbols(source, sizeSymbols);
?
【讨论】:
以上是关于“CA2000 在失去范围之前处理对象”,原因不明的主要内容,如果未能解决你的问题,请参考以下文章