I found an unusual sample in FCL code.
This is method in 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;
}
What impact on the execution logic has 'copyOfStream'?
It's done so that m_stream will be set to null even if Stream.Close()
throws an exception.
In response to comments
what kind of exception can be raised on Stream.Close()
When you close a stream, any buffered output is flushed, which can throw an exception, e.g. due to a network failure.
I'm not sure that this is a rationale. Usually we're calling Dispose in using block, and this means that variable will never used anyway
In the above, if Stream.Close() throws, then m_stream will already be null. With the following alternative, m_stream won't be set to null if Stream.Close() throws:
m_stream.Close(); // <== throws
m_stream = null; // <== not executed if Close() throws
But in this case if we're talking about exception-safety, someone can retry call to Dispose method and will face NullReferenceException
It won't throw a NullReferenceException because it tests for null:
if (copyOfStream != null && !m_leaveOpen)
copyOfStream.Close();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With