我有一个使用一些底层本机资源的对象,并且有一个指向下一个实例的指针,我将其迭代类似于:
MyObject begin = null;
try
{
begin = GetFirst();
while (begin != null)
{
MyObject next = begin.Next();
// do something with begin
begin.Dispose();
begin = next;
}
}
finally
{
if (begin != null)
{
begin.Dispose();
}
}
我得到了代码分析问题:
CA2202:Microsoft.Usage:对象'begin'可以在方法'x()'中多次处理。为避免生成System.ObjectDisposedException,不应在对象上多次调用Dispose。
任何想法如何在不压制它的情况下摆脱这个错误?
答案 0 :(得分:4)
在我看来,你的最后一段代码是不必要的。如果begin != null
,则您的while
循环应该继续,不是吗?
更新:看起来您正在尝试确保在抛出异常时处理begin
的最后获取值。试试这个:
MyObject begin = GetFirst();
while (begin != null)
{
MyObject next;
using (begin)
{
next = begin.Next();
// do something with begin
}
begin = next;
}
请注意,在上面的建议中,实际上您最终可能会遇到一个未曝光的对象:在next
块结束之前分配给using
的最后一个值。您的原始问题未涵盖此方案,因此我未在上述建议中解决此问题。但是,如果这是一个潜在的问题,这是值得考虑的事情。
答案 1 :(得分:0)
似乎Code Analysis认为在Dispose()
方法期间可能发生异常。如果是这种情况,您将输入finally块,其中包含对begin
已经处理过的非空引用。
请注意,如果您计划将调用包装到begin.Dispose()
以进行额外的错误捕获和处理,我只会更喜欢@ Dan的方法。 IMO,Dan的解决方案更优雅。
这是一个尝试 - 终止方法,删除警告:
MyObject begin = GetFirst();
MyObject next = null;
while (begin != null)
{
try
{
next = begin.Next();
// do something with begin
}
finally
{
begin.Dispose();
begin = next;
}
}
答案 2 :(得分:0)
你显然有一些识别链中第一项的机制,也许是其他一些对象或一些存储第一项的静态?
在最初调用dispose的代码中如何:
GetFirst().Dispose();
然后处置方法的唯一责任是处理当前项目及其子项:
public void Dispose()
{
if (Next() != null)
{
Next().Dispose();
}
}
这消除了在dispose方法中循环的任何需要。我还要看一下dispose pattern