C# enumerable property like .Any that accounts for nulls Brief Description:

A generic extension method that performs the same function as IEnumerable.Any(), but does not throw an error when passed a parameter with a null value.

Explanation:

Often times I will come across code that performs two steps on a nullable collection to make sure it contains elements. The first step checks to make sure the collection is not null, then the second step looks to see that there are greater than zero elements.

For example, to make sure a List&lt;T&gt; meets these qualifications before working through each element, code might look like this:

List&lt;int&gt; intList = new List&lt;int&gt;();

if (
    intList != null &amp;&amp;
    intList.Any()
    )
{
    foreach (int intElement in intList)
    {
        // logic here
. . .


To reiterate, just using .Any() above would be insufficient for the situation where intList hasn't yet been initialized.

Because this is a common occurrence in the code I maintain, I've come up with a generic extension method that performs the same function as the above, in one method:

static class CLR
{
    public static bool Populated&lt;TSource&gt;(this IEnumerable&lt;TSource&gt; source)
    {
        return source != null &amp;&amp; source.Any();
    }
. . .


... which renders the first block a little simpler:

if (intList.Populated())
{
    foreach (int intElement in intList)
    {
        // logic here
. . .


Are there suggestions for why this should not be implemented, or why it should be implemented in a different form?
My point of view is different depending on whether the the code that's returning null enumerables is a 3rd-party API or your own code.



3rd-Party

If the code that's returning null enumerables is a 3rd-party API, then I only have a few minor points to mention:


CLR is a very bad and misleading name for a class. In the .NET world CLR stands for Common Language Runtime, the part that's responsible for JIT-compiling CIL code (which all .net languages compile to), a bit like the JVM does for byte code / compiled Java.
I would have named Populated with a little Is prefix to read like IsPopulated, because I like Boolean functions/properties to read that way. But that's personal preference.


The implementation itself is nice &amp; clean, nothing to say about it (other than the C# 6 trick in t3chb0t's answer); I like that you named the this parameter source, it lines up with other framework-provided IEnumerable&lt;T&gt; extension methods, e.g. LINQ. TSource seems a bit verbose when T would have been sufficient, but I like descriptive generic type parameters so I'd leave it as is.

In the sample code, you have this:


if (
    intList != null &amp;&amp;
    intList.Any()
    )



That looks terrible; an if condition should fit one single line:

if (intList != null &amp;&amp; intList.Any())


Very long conditions that actually need to be multiple lines, should be extracted out of the if statement and into their own function with a meaningful name that captures the meaning of all these conditions:

if (IsValid(intList))


You get the idea; that's usually more commonly seen with LINQ queries and predicates though, but the concept is the same: if it's too much clutter to be readable, move it elsewhere and abstract it behind a meaningful identifier.



Your own

On the other hand, if the code that's returning null enumerables is under your control, there's a bigger issue.

Per Framework Design Guidelines 2nd Edition, p.256:


  DO NOT return null values from collection properties or from methods returning collections. Return an empty collection or an empty array instead.


See this SO Q&amp;A for more information about whether it's better to return null or an empty collection.

Instead of introducing an extension method to work around a serious design issue in your code base, you should be hunting down instances of IEnumerable&lt;T&gt;-returning methods and properties in that code base, and fixing them so that they return an empty enumerable instead of a null value:

return Enumerable.Empty&lt;Foo&gt;();


Then all you need to do is get rid of redundant but inoffensive null-checks everywhere in the code base, and new code wouldn't need any such null-checks.