The C# compiler will not optimize away the enumeration because the act of enumerating over a collection may produce side effects:
- In the case of an array, the act of indexing into the array implies a side effect (and the C# compiler rewrites
foreach
loops over arrays into indexing loops). - For other collections, the calls to
GetEnumerator()
andMoveNext()
imply side effects.
In both cases, the potential null
dereference is a side effect.
When invoking a [Conditional]
method, only the method call and its formal arguments will be omitted from the compiled code. Note that even arguments with side effects would be omitted. However, no surrounding code would be omitted.
My own tests show that even adding an explicit null
check will not coax the C# compiler into optimizing away the enumeration, even for a simple array.
Whether the JIT compiler optimizes away the enumeration code is another question. It might, if it can prove that the collection is always non-null
and that there are no other meaningful side effects. The JIT might be sophisticated enough to do this for arrays; I wouldn't bet on it, though. If the added overhead concerns you, place the enumeration code within an #if
region as @pid suggests.