I am always super annoyed when I have to write a bunch of if
statements whenever I have to traverse an object graph of possibly null objects. As there is not yet a ?.
operator I resorted to creating this wonderful piece of work: TryGetProperty
. Please tear it apart. This was written for LINQPad.
public bool TryGetProperty<TInstance, TFinal>(TInstance instance, Expression<Func<TInstance, TFinal>> propertyAccessor, out TFinal output)
{
var currentExpression = propertyAccessor.Body as MemberExpression;
var stack = new Stack<PropertyInfo>();
do
{
stack.Push(currentExpression.Member as PropertyInfo);
} while((currentExpression = currentExpression.Expression as MemberExpression) != null);
var failed = false;
object currentObject = instance;
while(!failed && stack.Count > 0 )
{
currentObject = stack.Pop().GetMethod.Invoke(currentObject, null);
failed = currentObject == null && stack.Count != 0;
}
output = failed ? default(TFinal) : (TFinal) currentObject;
return !failed;
}
Example call from the same file.
void Main() { List<Class1> instances = new List<Class1> { new Class1(), new Class1 { Class2 = new Class2 { Class3 = new Class3 { AProperty = "not null" } } }, new Class1 { Class2 = new Class2 { Class3 = new Class3() } } }; string propertyToGet; foreach(var instance in instances) { if(TryGetProperty(instance, c => c.Class2.Class3.AProperty, out propertyToGet) && propertyToGet != null) { "Yay!".Dump(); } else { "Boo!".Dump(); } } } public class Class1 { public Class2 Class2{ get; set; } } public class Class2 { public Class3 Class3 { get; set; } } public class Class3 { public string AProperty { get; set; } }
?.
operator for C# 6.0. :) \$\endgroup\$