Fluent null checking
When you want to access nested properties on an object, e.g. Person.Address.Postcode
, it’s annoying and bloated having to write this as a series of variable assignments and null checks at each stage if the properties are nullable. The set of extensions below allows the following example:
public string GetSomething(A myClass) { var property1 = myClass.Property1; if (property1 == null) { return string.Empty; } var property2 = property1.Property2; if (property2 == null) { return string.Empty; } return property2.Property3 ?? string.Empty; }
to be cleanly re-written as…
public string GetSomething(A myClass) { return myClass.With(x => x.Property1).With(x => x.Property2).Return(x => x.Property3, string.Empty); }
using these extensions:
using System; namespace Extensions { public static class MaybeMonadExtensions { public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator) where TResult : class where TInput : class { return o == null ? null : evaluator(o); } public static TResult Return<TInput, TResult>( this TInput o, Func<TInput, TResult> evaluator, TResult failureValue) where TInput : class { return o == null ? failureValue : evaluator(o); } public static TInput If<TInput>(this TInput o, Func<TInput, bool> evaluator) where TInput : class { if (o == null) { return null; } return evaluator(o) ? o : null; } public static TInput Unless<TInput>(this TInput o, Func<TInput, bool> evaluator) where TInput : class { if (o == null) { return null; } return evaluator(o) ? null : o; } public static TInput Do<TInput>(this TInput o, Action<TInput> action) where TInput : class { if (o == null) { return null; } action(o); return o; } } }
See http://www.codeproject.com/KB/cs/maybemonads.aspx for more details.