将IDisposable传递到父级IDisposable时,结果是什么? [英] What is the resulting behavior when an IDisposable is passed into a parent IDisposable

查看:102
本文介绍了将IDisposable传递到父级IDisposable时,结果是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天,在我们的代码库上运行Visual Studio代码分析后,以下代码突出显示为问题:

Yesterday, after running Visual Studio code analysis on our codebase, the following code was highlighted as an issue:

using (var stringReader = new StringReader(someString))
{
    using (var reader = XmlReader.Create(stringReader)) {
    // Code
    }
}

返回的警告是

警告CA2202对象'stringReader'可以在以下位置多次处置 方法(方法名称)".为了避免产生 System.ObjectDisposedException,您不应调用Dispose超过 一次在一个物体上.

Warning CA2202 Object 'stringReader' can be disposed more than once in method '(method name)'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.

搜索堆栈溢出后,我得到了大致的了解,如果我要创建一个包含IDisposable成员的自定义类,它应该实现IDisposable本身,并调用该成员的dispose()方法.

After searching stack overflow, I've come to the general understanding that if I were to create a custom class containing IDisposable members, it should implement IDisposable itself, and call the dispose() method of the member.

我的两个问题是

  • 在创建过程中对象X将对IDisposable对象Y的引用作为参数的所有情况下,假设对象X将拥有Y的所有权并从那时起调用X.dispose()将是正确的吗? 始终会导致呼叫Y.dispose()
  • 这是一段旧代码,警告消息中描述的异常从未报告过(据我所知).如果假设以上几点,为什么双using块不会导致两次调用stringReader.dispose()并因此引发异常?
  • In all cases where object X takes a reference to an IDisposable object Y as a parameter during creation, is it correct to assume that the object X will take ownership of Y and from that point onwards, calling X.dispose() will always result in calling Y.dispose()
  • This is an old piece of code and exceptions as described in the warning message have never been reported (to the best of my knowledge). If the above point is assumed, why does the double using block not result in calling stringReader.dispose() twice and therefore throwing an exception?

推荐答案

假设对象X拥有Y的所有权是正确的,并且从那时起,调用X.dispose()将始终导致调用Y.dispose()

is it correct to assume that the object X will take ownership of Y and from that point onwards, calling X.dispose() will always result in calling Y.dispose()

不,要假设这一点永远都是不可行的.让我们检查一下这种特殊情况:XmlReader.Create(Stream).

No, it is never save to assume that. Let's check this specific case: XmlReader.Create(Stream).

在参考资源中找到相当多的代码后,我发现Dispose方法调用了Close方法.那是很明显的.然后注意这段代码:

After going to quite some code in the Reference Source, I have found that the Dispose method calls the Close method. That is quite obvious. Then notice this piece of code:

public override void Close() {
    Close( closeInput );
}

因此,是否将关闭并丢弃备用流取决于设置closeInput的值,您可以通过

So whether the backing stream will be closed and disposed depends on the value of the setting closeInput, which you can set through the XmlReaderSettings.CloseInput setting.

因此,这里的答案是肯定的:您不能确定它是否被处置.您应该始终确保自己是.

So the answer here is a definite no: you can't be sure it is disposed. You should always make sure yourself it is.

这篇关于将IDisposable传递到父级IDisposable时,结果是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆