Say you are trying to read this property
var town = Staff.HomeAddress.Postcode.Town;
Somewhere along the chain a null could exist. What wo
@Oded's and others' answers still hold true in 2016 but c# 6 introduced the null-conditional operator which provides the elegance you are after.
using System;
public class Program
{
public class C {
public C ( string town ) {Town = town;}
public string Town { get; private set;}
}
public class B {
public B( C c ) {C = c; }
public C C {get; private set; }
}
public class A {
public A( B b ) {B = b; }
public B B {get; private set; }
}
public static void Main()
{
var a = new A(null);
Console.WriteLine( a?.B?.C?.Town ?? "Town is null.");
}
}
How often do you expect a null? If (and only if) it will be infrequent, I would use
try
{
var town = staff.HomeAddress.Postcode.Town;
// stuff to do if we could get the town
}
catch (NullReferenceException)
{
// stuff to do if there is a null along the way
}
As per encapsulation, it is always the duty of a class to make proper validation (i.e. null-checks) for it's fields (and properties) before returning them. So each object is responsible for its fields, you can choose to return null, empty string, or raise an exception and handle it one level up in the chain. Trying to work around this is like trying to work around encapsulation.
Here a solution using null coalescing operators that I put together for fun (other answers are better). If you except this as the answer I'll have to hunt you down and uh, take your keyboard away! :-)
Basically, if any object in Staff is null
its default will be used instead.
// define a defaultModel
var defaultModel = new { HomeAddress = new { PostCode = new { Town = "Default Town" } } };
// null coalesce through the chain setting defaults along the way.
var town = (((Staff ?? defaultModel)
.HomeAddress ?? defaultModel.HomeAddress)
.PostCode ?? defaultModel.HomeAddress.PostCode)
.Town ?? defaultModel.HomeAddress.PostCode.Town;
Disclaimer, I'm a javascript guy and we javascripters know that accessing an object's properties can get expensive - so we tend to cache just above everything, which is what the code above accomplishes (each property is only looked up once). With C#'s compilers and optimizers it probably isn't necessary to do it (some confirmation on this would be nice).
Can't test right now, but wouldn't something like this work?
if (Staff??Staff.HomeAdress??Staff.HomeAddress.Postcode??Staff.HomeAddress.Postcode.Town != null)
{
var town = Staff.HomeAddress.Postcode.Town
}
The best way would be to avoid violating the law of Demeter.
var town = Staff.GetTown();
And in Staff
:
string GetTown()
{
HomeAddress.GetTown();
}
And in HomeAddress
:
string GetTown()
{
PostCode.GetTown();
}
And in PostCode
:
string GetTown()
{
Town.GetTownName();
}
Update:
Since you don't have control over this, you can use short circuit evaluation:
if(Staff != null
&& Staff.HomeAddress != null
&& Staff.HomeAddress.PostCode != null
&& Staff.HomeAddress.PostCode.Town != null)
{
var town = Staff.HomeAddress.Postcode.Town;
}