Search code examples
c#.netlinqnullable

How to get C# null state to convert List<T?> to List<T>


I am utilizing nullable reference types in the C# nullable context.

I am taking a List<string>, then transforming it to a new List<string?> with a Select like so. I then filter out the nulls with a Where, but the underlying type is still List<string?>.

strings = strings
    .Select(s => method.ThatReturnsNullableString(s))
    .Where(s => s is not null)
    .ToList();

When I try to use this as a List<string>, I get a CS8619 compiler warning. An easy solution is to use the ! null-forgiving operator and the warning goes away, but I try to use this as sparingly as possible.

Another solution is to use .Cast<string>, but I would assume this adds runtime overhead for no reason.

Have I not sufficiently proven to the compiler that the collection is of type string, or is there something I'm missing?


Solution

  • .Where(s => s is not null) will suppress the null-only items and will keep items of type string?, so the result will be of type List<string?>.

    Use .OfType<string>(), it will skip null values and casts string? to string, It's the equivalent to .Where(s => s is not null).Cast<string>().

    strings = strings
        .Select(s => method.ThatReturnsNullableString(s))
        .OfType<string>()
        .ToList(); // List<string>