VS2010代码分析期间的IDisposable和CA2000警告
我需要一些建议,希望有人能帮助我。 我有以下类结构(简化):
public class Bar: IDisposable {...}
public abstract class FooBase: IDisposable
{
Bar bar;
bool disposed;
internal FooBase(Bar bar)
{
this.bar=bar;
}
public void Dispose()
{
Dispose(true);
GC.SupressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
this.bar.Dispose();
}
this.disposed = true;
}
}
}
public FooA: Foo {...}
public FooB: Foo {...}
public static class FooProvider
{
public static FooA GetFooA()
{
Bar bar = new Bar();
...
return new FooA(bar);
}
public static FooB GetFooB()
{
Bar bar = new Bar();
...
return new FooB(bar);
}
...
}
当我对此运行代码分析时,我在FooProvider类的所有'CreateFooX()'方法上得到了警告CA2000。 此警告提供以下消息:
“Microsoft。可靠性:在方法'FooProvider.GetFooX()'中,在对象'bar'上调用System.IDisposable.Dispose之前,所有对它的引用都超出了范围。
微软建议永远不要压制这个警告,但我并不确定它对代码中真正问题的警告。 诚然,在我们考虑的任何'CreateFooX()'方法中,'bar'并没有被抛弃,而是指向它的'FooX'对象,它最终将被处置,并且将会依次处理'酒吧'。
我是否理解Dispose模式应该如何工作,以及我的代码中存在一些基本缺陷,或者我应该只是抑制此警告?
编辑
由于一些评论,我尝试将工厂方法修改为以下内容:
public static class FooProvider
{
public static FooA GetFooA()
{
Bar bar = null;
try
{
bar = new Bar();
...
return new FooA(bar);
}
catch
{
if (bar != null) bar.Dispose();
throw;
}
}
...
}
但我仍然得到同样的警告。 我猜它只是一个误报,我很安心。
感谢您的任何建议。
这是Code Analysis的典型误报。 它真的无法理解你的代码的内在情况,所以它会给出一个通用的答案。 谨慎行事,但每当你确认你有误报时,你可以放心地忽略它。
这不是误报。 如果在创建Bar
之后但在将其传递给Foo
构造函数之前抛出异常,该怎么办? 我看到几个代码路径可能不会处理一个或多个对象。
你的一次性模式对我来说似乎有点不合适。 我不认为你应该调用bar.Dispose在FooBase类。 为了安全处理您正在处理的物品并能够安全地呼叫处理多次,我会重新考虑这种方法。
private bool _disposed;
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
protected virtual void Dispose( bool disposing )
{
if ( disposing )
{
if ( !_disposed )
{
if ( Bar != null )
{
Bar.Dispose();
}
_disposed = true;
}
}
}
至于错误,我认为这应该照顾静态分析警告。 我在一个测试项目中按如下方式实现了您的代码,启用了所有静态分析警告,但没有警告问题。
public class Bar : IDisposable
{
private bool _disposed;
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
protected virtual void Dispose( bool disposing )
{
if ( disposing )
{
if ( !_disposed )
{
_disposed = true;
}
}
}
}
public abstract class FooBase : IDisposable
{
public Bar Bar
{
get;
set;
}
internal FooBase( Bar bar )
{
Bar = bar;
}
private bool _disposed;
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
protected virtual void Dispose( bool disposing )
{
if ( disposing )
{
if ( !_disposed )
{
if ( Bar != null )
{
Bar.Dispose();
}
_disposed = true;
}
}
}
}
public class FooA : FooBase
{
public FooA( Bar bar )
: base( bar )
{
}
}
public static class FooProvider
{
public static FooA GetFooA()
{
Bar bar;
using ( bar = new Bar() )
{
return new FooA( bar );
}
}
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void StaticAnalysisTest()
{
Assert.IsNotNull( FooProvider.GetFooA().Bar );
}
}
我希望这是有帮助的。
链接地址: http://www.djcxy.com/p/69037.html上一篇: IDisposable and CA2000 warning during VS2010 Code Analysis