Say you are trying to read this property
var town = Staff.HomeAddress.Postcode.Town;
Somewhere along the chain a null could exist. What would be the best way of reading Town?
I have been experimenting with a couple of extension methods...
public static T2 IfNotNull<T1, T2>(this T1 t, Func<T1, T2> fn) where T1 : class { return t != null ? fn(t) : default(T2); } var town = staff.HomeAddress.IfNotNull(x => x.Postcode.IfNotNull(y=> y.Town));
or
public static T2 TryGet<T1, T2>(this T1 t, Func<T1, T2> fn) where T1 : class { if (t != null) { try { return fn(t); } catch{ } } return default(T2); } var town = staff.TryGet(x=> x.HomeAddress.Postcode.Town);
Obviously these are just abstracting away the logic and making the code (a little) more readable.
But is there a better/ more efficient way?
EDIT:
In my particular case the objects are being returned from a WCF service and I have no control over the architecture of those objects.
EDIT 2:
There is also this method:
public static class Nullify { public static TR Get<TF, TR>(TF t, Func<TF, TR> f) where TF : class { return t != null ? f(t) : default(TR); } public static TR Get<T1, T2, TR>(T1 p1, Func<T1, T2> p2, Func<T2, TR> p3) where T1 : class where T2 : class { return Get(Get(p1, p2), p3); } /// <summary> /// Simplifies null checking as for the pseudocode /// var r = Pharmacy?.GuildMembership?.State?.Name /// can be written as /// var r = Nullify( Pharmacy, p => p.GuildMembership, g => g.State, s => s.Name ); /// </summary> public static TR Get<T1, T2, T3, TR>(T1 p1, Func<T1, T2> p2, Func<T2, T3> p3, Func<T3, TR> p4) where T1 : class where T2 : class where T3 : class { return Get(Get(Get(p1, p2), p3), p4); } }
from this article http://qualityofdata.com/2011/01/27/nullsafe-dereference-operator-in-c/
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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With