友好的方式来处理物体
作为Visual Studio 2010(主要是C#4.0)开发标准的一部分,我们开启了代码分析。 在我审查最近为新项目提交的代码时,我看到了很多
CA2000:Microsoft.Reliability:在'XYZ'方法中,对象'ABC'不是沿着所有异常路径处理的。 调用System.IDisposable.Dispose对象'ABC'之前,所有对它的引用超出范围。
警告。 问题是,我没有做任何事情似乎可以消除警告 - 我花了几个小时在网上冲浪,并尽我所能地尝试。
首先,让我清楚,我不是在谈论如何简单地使用块来恰当地处理局部变量 - 这不是问题。 在我的情况下,当对象由方法返回或分配给方法内的另一个对象时,这些警告就会出现。
以下是包含四个此类警告的代码示例:
public void MainMethod()
{
var object1 = CreateFirstObject(); // Warning here
var object2 = CreateSecondObject(); // Warning here
SomeCollectionProperty.Add(object1);
SomeCollectionProperty.Add(object2);
}
private SomeObject CreateFirstObject()
{
var theObject = new SomeObject() // Warning here
{
FirstProperty = "some value",
// ...
};
return theObject;
}
private SomeOtherObject CreateSecondObject()
{
var theObject = new SomeOtherObject() // Warning here
{
FirstProperty = "a different value",
// ...
};
return theObject;
}
我已经评论了警告发生的地方。
我已经尝试重构MSDN文章(此处)中描述的创建方法,但警告仍然出现。
更新我应该注意,SomeObject和SomeOtherObject都实现了IDisposable。
另外,尽管对象初始值设定项可能是问题的一个组成部分,但请记住,初始值设定项被隔离到两个私有方法,并且与MainMethod中的警告无关。
任何人都可以告诉我如何正确实施这些方法来消除CA2000警告?
在这种情况下,CA2000正在检测到的问题是,如果在将异常从方法中移出之前发生异常,则可丢弃实例可能会“孤立”。 例如,CreateFirstObject的“正确”实现看起来如下所示:
private SomeObject CreateFirstObject()
{
var theObject = new SomeObject();
try
{
theObject.FirstProperty = "some value";
}
catch
{
theObject.Dispose();
throw;
}
return theObject;
}
根据你所描述的关于MainMethod的期望行为,它的“正确”实现可能看起来像这样:
public void MainMethod()
{
var object1 = CreateFirstObject();
try
{
SomeCollectionProperty.Add(object1);
var object2 = CreateSecondObject();
try
{
SomeCollectionProperty.Add(object2);
}
catch
{
object2.Dispose();
throw;
}
}
catch
{
object1.Dispose();
SomeCollectionProperty.Remove(object1); // Not supposed to throw if item does not exist in collection.
throw;
}
}
摆脱警告的一种方法是在代码中将其抑制:
[SuppressMessage(
"Microsoft.Reliability",
"CA2000:DisposeObjectsBeforeLosingScope",
Justification = "Factory method")]
但这不是问题的真正解决方案 。
这里介绍一种解决方案:如何在所有权转移后摆脱CA2000警告?
在上面提到的链接中,基本上声明将对象添加到实现ICollection<T>
的集合中,但我没有测试过。
如果将返回的对象包装在main块中,或者实现一个finally来处理这些对象,会发生什么?
SomeOtherObjects是否需要实现IDisposable?
链接地址: http://www.djcxy.com/p/63013.html