5

我在 FCL 代码中发现了一个不寻常的示例。

这是 System.IO.BinaryReader 中的方法:

    protected virtual void Dispose(bool disposing) { 
        if (disposing) { 
            Stream copyOfStream = m_stream;
            m_stream = null; 
            if (copyOfStream != null && !m_leaveOpen)
                copyOfStream.Close();
        }
        m_stream = null; 
        m_buffer = null;
        m_decoder = null; 
        m_charBytes = null; 
        m_singleChar = null;
        m_charBuffer = null; 
    }

“copyOfStream”对执行逻辑有什么影响?

4

1 回答 1

9

这样做是为了即使Stream.Close()抛出异常, m_stream 也会被设置为 null。

回应评论

Stream.Close() 可以引发什么样的异常

当您关闭一个流时,任何缓冲的输出都会被刷新,这可能会引发异常,例如由于网络故障。

我不确定这是一个基本原理。通常我们在 using 块中调用 Dispose,这意味着该变量无论如何都不会使用

在上面,如果 Stream.Close() 抛出,那么 m_stream 将已经为空。使用以下替代方法,如果 Stream.Close() 抛出,m_stream 将不会设置为 null:

m_stream.Close(); // <== throws
m_stream = null;  // <== not executed if Close() throws

但是在这种情况下,如果我们谈论的是异常安全,有人可以重试调用 Dispose 方法,并且将面临 NullReferenceException

它不会抛出 NullReferenceException,因为它会测试 null:

if (copyOfStream != null && !m_leaveOpen)
        copyOfStream.Close();
于 2012-11-29T21:10:07.553 回答