问题描述
昨天,在我们的代码库上运行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
}
}
返回的警告是
搜索堆栈溢出后,我得到了大致的了解,如果我要创建一个包含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, callingX.dispose()
will always result in callingY.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 callingstringReader.dispose()
twice and therefore throwing an exception?
推荐答案
不,要假设这一点永远都是不可行的.让我们检查一下这种特殊情况: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
的值,您可以通过 XmlReaderSettings.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时,结果是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!