edit 2015 This question and its answers are no longer relevant. It was asked before the advent of C# 6, which has the null propagating opertor (?.), which obviates the hacky-workarounds discussed in this question and subsequent answers. As of 2015, in C# you should now use Form.ActiveForm?.ActiveControl?.Name.
I've been thinking about the null propagation problem in .NET, which often leads to ugly, repeated code like this:
Attempt #1 usual code:
string activeControlName = null; var activeForm = Form.ActiveForm; if (activeForm != null) { var activeControl = activeForm.ActiveControl; if(activeControl != null) { activeControlname = activeControl.Name; } } There have been a few discussions on StackOverflow about a Maybe<T> monad, or using some kind of "if not null" extension method:
Attempt #2, extension method:
// Usage: var activeControlName = Form.ActiveForm .IfNotNull(form => form.ActiveControl) .IfNotNull(control => control.Name); // Definition: public static TReturn IfNotNull<TReturn, T>(T instance, Func<T, TReturn> getter) where T : class { if (instance != null ) return getter(instance); return null; } I think this is better, however, there's a bit of syntactic messy-ness with the repeated "IfNotNull" and the lambdas. I'm now considering this design:
Attempt #3, Maybe<T> with extension method
// Usage: var activeControlName = (from window in Form.ActiveForm.Maybe() from control in window.ActiveControl.Maybe() select control.Name).FirstOrDefault(); // Definition: public struct Maybe<T> : IEnumerable<T> where T : class { private readonly T instance; public Maybe(T instance) { this.instance = instance; } public T Value { get { return instance; } } public IEnumerator<T> GetEnumerator() { return Enumerable.Repeat(instance, instance == null ? 0 : 1).GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } public static class MaybeExtensions { public static Maybe<T> Maybe<T>(this T instance) where T : class { return new Maybe<T>(instance); } } My question is: is this an evil abuse of extension methods? Is it better than the old usual null checks?
string result=One.Maybe(o=>o.Two.Three.Four.Foo);string cityName= Employee.Maybe(e=>e.Person.Address.CityName);As answered in stackoverflow.com/a/2866634/52277