Reputation: 5793
I'v been playing around with some shorter hand ways of checking multiple nested objects to see if any are null before proceeding. I'm trying to replace the multiple nested if statements into a single statement if possible using Null-conditional Operators.
So far i have something like this:
if ((Object1?.Object2?.Object3?.Object4 != null) ? true : false)
{
...
}
Would the above be effective at identifying if either Object1 2 3 or 4 is null and return a false if so? I'm interested to hear if anyone has any better solutions?
TIA
Upvotes: 1
Views: 1573
Reputation: 71591
What you have is currently the best way to do exactly what you want. I wanted to answer in order to illustrate what's necessary if you don't have access to the latest C# 6 language features. This is the next most developer-friendly way to make the same check in .NET 3.5-4.0:
//boilerplate, off in your extension method library
public static TOut OrDefault<TIn, TOut>(this TIn input,
Func<TIn, TOut> possiblyNullFunc)
{
try { return possiblyNullFunc(input); }
catch (NullReferenceException) //for most reference types
{ return default(TOut); }
catch (InvalidOperationException) //for Nullable<T>
{ return default(TOut); }
}
...
//usage
if (Object1.OrDefault(o=>o.Object2.Object3.Object4) != null)
{
...
}
It functions pretty well, until you try to use InvalidOperationException
in your own classes for situations other than null member access.
Still beats the pants off this, especially if you have to make this check a lot:
if(Object1 != null
&& Object1.Object2 != null
&& Object1.Object2.Object3 != null
&& Object1.Object2.Object3.Object4 != null)
{
...
}
Upvotes: 0
Reputation: 236328
You don't need to return false or true - boolean condition itself has boolean value:
if (Object1?.Object2?.Object3?.Object4 != null)
This part is a completely valid option for checking nested objects if any of them is null. You can find exactly same example in null-conditional operator documentation:
// null if customers, the first customer, or Orders is null
int? count = customers?[0]?.Orders?.Count();
And explanation:
The last example demonstrates that the null-condition operators are short-circuiting. If one operation in a chain of conditional member access and index operation returns null, then the rest of the chain’s execution stops.
Upvotes: 6
Reputation: 127603
The code
public void Foo()
{
if ((Object1?.Object2?.Object3?.Object4 != null) ? true : false)
{
...
}
}
is logically equivalent to
public void Foo()
{
if ((NullCheck(Object1) != null) ? true : false)
{
...
}
}
private Object4Type NullCheck(Object1Type object1)
{
if(!Object.RefrenceEquals(object1, null)) //This is "Object1?."
{
var tmpObject2 = tmpObject1.Object2;
if(!Object.RefrenceEquals(tmpObject2, null)) //This is "Object2?."
{
var tmpObject3 = tmpObject2.Object3;
if(!Object.RefrenceEquals(tmpObject3, null)) //This is "Object3?."
{
return tmpObject3.Object4;
}
}
}
return default(Object4Type);
}
or if Object4Type is a struct
public void Foo()
{
if ((NullCheck(Object1) != null) ? true : false)
{
...
}
}
private Nullable<Object4Type> NullCheck(Object1Type object1)
{
if(!Object.RefrenceEquals(object1, null)) //This is "Object1?."
{
var tmpObject2 = tmpObject1.Object2;
if(!Object.RefrenceEquals(tmpObject2, null)) //This is "Object2?."
{
var tmpObject3 = tmpObject2.Object3;
if(!Object.RefrenceEquals(tmpObject3, null)) //This is "Object3?."
{
return tmpObject3.Object4;
}
}
}
return default(Nullable<Object4Type>);
}
So your ...
will only be run if all objects are not null and if a lower level object is null, the later objects never get evaluated.
Upvotes: 0