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.