如何处理通过 Next 属性迭代的对象?
我有一个对象,它使用一些底层本机资源,并且有一个指向下一个实例的指针,我对其进行迭代,类似于:
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.ObjectDisposeException,您不应在一个对象上多次调用 Dispose。
知道如何在不抑制它的情况下摆脱这个错误吗?
I have an object that uses some underlying native resources, and has a pointer to the next instance, which I iterate through similar to:
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();
}
}
I get the code analysis problem:
CA2202: Microsoft.Usage: Object 'begin' can be disposed more than once in method 'x()'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.
Any idea how I can get rid of this error without suppressing it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
显然,您有某种机制来识别链中的第一项,也许是其他一些对象或存储第一项的静态变量?
在最初调用 dispose 的代码中怎么样:
那么 dispose 方法的唯一责任是处置当前项及其子项:
这消除了在 dispose 方法中循环的任何需要。我还会看一下 处置模式
You obviously have some mechanism for identifying the first item in the chain, perhaps some other object or some static that is storing the first item?
How about in your code that is originally calling dispose:
Then the only responsibility for the dispose method is to dispose the current item and it's children:
This eliminates any need to loop within the dispose method. I would also take a look at the dispose pattern
代码分析似乎认为在
Dispose()
方法期间可能会发生异常。如果是这种情况,您将输入带有对begin
的已处置但非空引用的finally 块。请注意,如果您计划将对
begin.Dispose()
的调用包装在额外的错误捕获和处理中,我只会比 @Dan 更喜欢这种方法。 IMO,丹的解决方案更加优雅。这是消除警告的 try-finally 方法:
It appears that Code Analysis considers it possible for an exception to occur during the
Dispose()
method. Were that to be the case, you would enter the finally block with an already-disposed-albeit-non-null reference tobegin
.Note that I would only prefer this approach to @Dan's if you plan to wrap the call to
begin.Dispose()
in additional error trapping and handling. IMO, Dan's solution is more elegant.Here is a try-finally approach that removes the warning:
在我看来,你的最后一段代码确实是不必要的。如果
begin != null
,那么你的while
循环应该继续,不是吗?更新:看起来您正在尝试确保在引发异常的情况下处理最后获得的
begin
值。试试这个:请注意,在上面的建议中,实际上仍然可能会出现未处理的对象:在
using 结束之前分配给
next
的最后一个值> 阻止。您原来的问题中没有涵盖这种情况,因此我没有在上述建议中解决它。不过,如果这是一个潜在的问题,那就值得考虑。It certainly seems to me that your last block of code is unnecessary. If
begin != null
, then yourwhile
loop should have continued, no?UPDATE: It looks like you're trying to ensure the last obtained value for
begin
is disposed in case an exception is thrown. Try this:Note that in the above suggestion, it could actually still happen that you end up with an undisposed object: the last value assigned to
next
, before the end of theusing
block. This scenario wasn't covered in your original question, so I haven't addressed it in the above suggestion. It's something to consider, though, if that's a potential problem.