if (foo != null) { // Business as usual }
Say you have the following classes (exaggerated, the property "First" in class "Name" would usually just be a string):
public class Person { public Name Name { get; set; } } public class Name { public First First { get; set; } } public class First { public string Value { get; set; } }
And the following collection:
var people = new[] { new Person { Name = new Name { First = new First { Value = "John" } } }, new Person { Name = new Name { First = new First { Value = "Eric" } } }, new Person { Name = new Name { First = new First { Value = "Joel" } } }, new Person { Name = new Name { First = new First { Value = null } } }, new Person { Name = new Name { First = new First() } }, new Person { Name = new Name() }, new Person { Name = null }, new Person(), null };
On a given query, you might see something like:
private void PrintFirstNames(IEnumerable<Person> people) { if (people != null) { foreach (var person in people) { if (person != null && person.Name != null && person.Name.First != null && person.Name.First.Value != null) { Console.WriteLine(person.Name.First.Value); } } } }
Which can, of course, be written more concisely in LINQ:
private void PrintFirstNamesLinq(IEnumerable<Person> people) { var names = people.Where(p => p != null).Select(p => p.Name) .Where(n => n != null).Select(n => n.First) .Where(f => f != null).Select(f => f.Value); foreach (var name in names) { Console.WriteLine(name); } }
However, after writing a handy little extension method called NonNull:
public static IEnumerable<R> NonNull<T, R>(this IEnumerable<T> source, Func<T, R> action) { if (source == null) { yield break; } foreach (var val in source.Where(s => s != null).Select(action).Where(val => val != null)) { yield return val; } }
It can be written even more concisely:
private void PrintFirstNamesNonNull(IEnumerable<Person> people) { var names = people.NonNull(p => p).NonNull(p => p.Name).NonNull(p => p.First).NonNull(p => p.Value); foreach (var name in names) { Console.WriteLine(name); } }
And even more concisely with a ForEach extension method (see here for code and the debate surrounding it):
private void PrintFirstNamesNonNullForEach(IEnumerable<Person> people) { people.NonNull(p => p).NonNull(p => p.Name).NonNull(p => p.First).NonNull(p => p.Value).ForEach(Console.WriteLine); }Another win for C# extension methods (and Monads, but I suppose that's another discussion).