In LINQ, select all values of property X where X != null

C#Linq

C# Problem Overview


Is there a shorter way to write the following? (Something that would check for null without explicitly writing != null)

from item in list 
where item.MyProperty != null 
select item.MyProperty

C# Solutions


Solution 1 - C#

You can use the OfType operator. It ignores null values in the source sequence. Just use the same type as MyProperty and it won't filter out anything else.

// given:
// public T MyProperty { get; }
var nonNullItems = list.Select(x => x.MyProperty).OfType<T>();

I would advise against this though. If you want to pick non-null values, what can be more explicit than saying you want "the MyProperties from the list that are not null"?

Solution 2 - C#

You could define your own extension method, but I wouldn't recommend that.

public static IEnumerable<TResult> SelectNonNull<T, TResult>(this IEnumerable<T> sequence,Func<T, TResult> projection)
{
   return sequence.Select(projection).Where(e => e != null);
}

I don't like this one because it mixes two concerns. Projecting with Select and filtering your null values are separate operations and should not be combined into one method.


I'd rather define an extension method that only checks if the item isn't null:

public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T> sequence)
{
   return sequence.Where(e => e != null);
}

public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> sequence)
    where T : struct
{
   return sequence.Where(e => e != null).Select(e => e.Value);
}

This has only a single purpose, checking for null. For nullable value types it converts to the non nullable equivalent, since it's useless to preserve the nullable wrapper for values which cannot be null.

With this method, your code becomes:

list.Select(item => item.MyProperty).WhereNotNull()

Solution 3 - C#

I tend to create a static class containing basic functions for cases like these. They allow me write expressions like

var myValues myItems.Select(x => x.Value).Where(Predicates.IsNotNull);

And the collection of predicate functions:

public static class Predicates
{
    public static bool IsNull<T>(T value) where T : class
    {
        return value == null;
    }

    public static bool IsNotNull<T>(T value) where T : class
    {
        return value != null;
    }

    public static bool IsNull<T>(T? nullableValue) where T : struct
    {
        return !nullableValue.HasValue;
    }

    public static bool IsNotNull<T>(T? nullableValue) where T : struct
    {
        return nullableValue.HasValue;
    }

    public static bool HasValue<T>(T? nullableValue) where T : struct
    {
        return nullableValue.HasValue;
    }

    public static bool HasNoValue<T>(T? nullableValue) where T : struct
    {
        return !nullableValue.HasValue;
    }
}

Solution 4 - C#

There is no way to skip a check if it exists.

Solution 5 - C#

// if you need to check if all items' MyProperty doesn't have null

if (list.All(x => x.MyProperty != null))
// do something

// or if you need to check if at least one items' property has doesn't have null

if (list.Any(x => x.MyProperty != null))
// do something

But you always have to check for null

Solution 6 - C#

get one column in the distinct select and ignore null values:

 var items = db.table.Where(p => p.id!=null).GroupBy(p => p.id)
                                .Select(grp => grp.First().id)
                                .ToList();

Solution 7 - C#

This is adapted from CodesInChaos's extension method. The name is shorter (NotNull) and more importantly, restricts the type (T) to reference types with where T : class.

    public static IEnumerable<T> NotNull<T>(this IEnumerable<T> source) where T : class
    {
        return source.Where(item => item != null);
    }

Solution 8 - C#

I know i am a bit late to the party but I found a IMO very elegant sollution to this problem. I wrote an extension method to chain onto my LINQ queries:

public static IEnumerable<T> DiscardNullValues<T>(this IEnumerable<T?> nullable)
    {
        foreach (var item in nullable)
        {
            if (item is not null) yield return item;
        }
    }

Works like a charm.

Solution 9 - C#

This is a feature that have been proposed to the dotnet/runtime issue tracker.

See this comment that proposes a SelectNotNull function : https://github.com/dotnet/runtime/issues/30381#issuecomment-806396119

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIlya KoganView Question on Stackoverflow
Solution 1 - C#R. Martinho FernandesView Answer on Stackoverflow
Solution 2 - C#CodesInChaosView Answer on Stackoverflow
Solution 3 - C#AnthonyView Answer on Stackoverflow
Solution 4 - C#abatishchevView Answer on Stackoverflow
Solution 5 - C#Vlad BezdenView Answer on Stackoverflow
Solution 6 - C#Jorge SantosView Answer on Stackoverflow
Solution 7 - C#Doug DomenyView Answer on Stackoverflow
Solution 8 - C#lukgerView Answer on Stackoverflow
Solution 9 - C#cube45View Answer on Stackoverflow