In most examples that you find on the web when explicitly not using "using", the pattern looks something like:
SqlConnection c = new SqlConnection(@"...");
try {
c.Open();
...
} finally {
if (c != null) //<== check for null
c.Dispose();
}
If you do use "using" and look at the generated IL code, you can see that it generates the check for null
L_0024: ldloc.1
L_0025: ldnull
L_0026: ceq
L_0028: stloc.s CS$4$0000
L_002a: ldloc.s CS$4$0000
L_002c: brtrue.s L_0035
L_002e: ldloc.1
L_002f: callvirt instance void [mscorlib]System.IDisposable::Dispose()
L_0034: nop
L_0035: endfinally
I understand why the IL gets translated to check for null (doesn't know what you did inside the using block), but if you're using try..finally and you have full control of how the IDisposable object gets used inside the try..finally block, do you really need to check for null? if so, why?