I have a question on programming style and C# language design in general, I'd love to know if there is a better way to do what I'm doing.
If you have a complex data object, with properties that can be null but you want to check or operate on data if it is there, you cannot write a line like so
if(Myobject.MyNestedObject != null || Myobject.MyNestedObject.Property != null)
{
//code
}
Because the compiler will actually call both lines of code to evaluate the if statement.
Instead you must (I believe) write :
if(Myobject.MyNestedObject != null)
{
if(Myobject.MyNestedObject.Property != null)
{
//code
}
}
Is there a better style than this? I'm trying to think of how to use null coalesce (??) but it would still throw if you try to use anything of MyNestedObject in the same statement.
More info:
L_01b4: ldarg.1
L_01b5: callvirt instance class [Myassembly]MyClass.MyObject [MyAssembly]MyClass::get_MyObject()
L_01ba: brtrue.s L_01cc
L_01bc: ldarg.1
L_01bd: callvirt instance class [MyAssembly]MyClass.MyObject [MyAssembly]MyClass::get_MyObject()
L_01c2: callvirt instance class [MyAssembly]MyClass.MyNestedObject [MyAssembly]MyClass.MyNestedObject::get_MyNestedObject()
L_01c7: ldnull
L_01c8: ceq
L_01ca: br.s L_01cd
L_01cc: ldc.i4.0
L_01cd: stloc.2
L_01ce: ldloc.2
L_01cf: brtrue L_0285
L_01d4: nop
From my understanding it's saying that at L_01ba if the call returns true, not null or non-0 (i.e if the object is null, the branch isn't taken and then control flow continues linearly). This then will of course execute L_01c2 which will throw a null reference exception, as Myclass.MyObject is null.
Have I missed something. This is the .net 3.5 C# compiler.