Tutorial :C# Nested null checks in if statements



Question:

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.


Solution:1

Combining @Chris and @aJ answer:

I think you want the && operator, not ||.

if (Myobject.MyNestedObject != null &&      Myobject.MyNestedObject.Property != null)  {      //code  }  

And C#'s && operator use short-circuit evaluation, so if the first expression returns false, the second expression will not be evaluated.

...


Solution:2

if( Myobject.MyNestedObject != null &&                Myobject.MyNestedObject.Property != null)  {  //code  }  


Solution:3

C# uses lazy checking, so your first code should be fine (with || changed to && of course!)

Update - Here it is: http://msdn.microsoft.com/en-gb/library/6373h346.aspx " The operation

x || y

corresponds to the operation

x | y

except that if x is true, y is not evaluated (because the result of the OR operation is true no matter what the value of y might be). This is known as "short-circuit" evaluation. "

Update again - should be using &&!


Solution:4

I'm going to add the obligatory advice that having to dig through layers of public properties usually means you are exposing too much internal state, and that the classes you are traversing should be doing this work for you. I would also expect an object to ensure its properties do not return null in the first place.

There are edge cases of course, but these are good rules of thumb.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »