TheLethalCoder TheLethalCoder - 1 year ago 88
C# Question

Null conditional operator and void methods

Before C# 6 I would write code to dispose of an object like:

if (_odbcConnection != null)
{
_odbcConnection.Close();
_odbcConnection.Dispose();
_odbcConnection = null;
}


With 6 I can write much less code:

_odbcConnection?.Close();
_odbcConnection?.Dispose();
_odbcConnection = null;


But are the two the equivalent?

Answer Source

Your two lower examples are almost equal. But the second block

_odbcConnection?.Close();
_odbcConnection?.Dispose();
_odbcConnection = null;

will be translated by the compiler to something like

var tmp1 = _odbcConnection;
if (tmp1 != null) tmp1.Close();
var tmp2 = _odbcConnection;
if (tmp2 != null) tmp2.Dispose();
_odbcConnection = null;

This means that this version is thread-safe, while the first (with the outer if clause) is not. If some mysterious thread would set _odbcConnection to null after the if but before Close() or Dispose(), a NullReferenceException would be thrown.

By using the null-conditional-operator you avoid this problem, because the reference is first stored in a compiler generated variable and then checked and used.


The above translation only applies to fields and properties. For local variables (only in scope of a single method, e.g. method parameters), this translation is not necessary and the code ends up like

if (_odbcConnection != null) _odbcConnection.Dispose();

That is because local variables cannot be changed by different threads.

And of course this is only the generated C#. In IL you may not see this anymore as it is either optimized away or obsolete, because in IL the reference value is loaded into a register and then compared. Again, another thread can no longer change that value in the register. So on IL level this discussion is somewhat pointless.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download