score:76

Accepted answer

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"?

score:0

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

score:1

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);
    }

score:1

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.

score:3

// 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

score:3

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();

score:4

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

score:14

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;
    }
}

score:52

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()

Related Query

More Query from same tag