Who doesn’t love LINQ? Who doesn’t love extension methods in .NET?
Unfortunately, Microsoft could have made things easier for developers by handling nulls gracefully. What do I mean? Take the following code as an example:
IEnumerable<int> numbers = null; if (numbers.Any()) { }
Obviously, as a programmer you would know that you should get a NullReferenceException from the above code. Below is the correct way to write that function:
IEnumerable<int> numbers = null; if ((numbers != null) && (numbers.Any())) { }
Simple and logical fix, but it’s just “noisy”. When dealing with an extension method, I disagree with how null references were handled in the LINQ libraries. Any extension function should detect null and return early (when possible). I believe that Microsoft’s view and defense is that an IEnumerable
Below is the decompiled implementation of the .Any() LINQ extension method (courtesy of .Net Reflector v6).
[__DynamicallyInvokable] public static bool Any<TSource>(this IEnumerable<TSource> source) { if (source == null) { throw Error.ArgumentNull("source"); } using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { if (enumerator.MoveNext()) { return true; } } return false; }
The following simple change to the above method would remove all of that extra “noise” and make our code easier to read.
[__DynamicallyInvokable] public static bool Any<TSource>(this IEnumerable<TSource> source) { if (source == null) return(false); using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { if (enumerator.MoveNext()) { return true; } } return false; }
Of course, the other solution (and recommended best practice) is to not return null from a function that returns an IEnumerable, but to instead return an empty collection. Unfortunately, when dealing with other people’s code or libraries you may not have that luxury. Below is a simple and efficient example of how to NOT return null for an IEnumerable result. Please note that the example is contrived and a String.Split function already exists.
public IEnumerable<string> Split(string input, string value) { if (input == null) return(new string[0]); ... }
So when you’re writing you own extension methods in .NET, do the world a favor and handle null much better.