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:
1 2 3 | 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:
1 2 3 | 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).
1 2 3 4 5 6 7 8 9 10 11 12 13 | [__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.
1 2 3 4 5 6 7 8 9 10 11 | [__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.
1 2 3 4 | 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.