ykasur
ykasur

Reputation: 215

Why is a Warning about a nullable type issued, even though there can be no null value?

Why do I get a Warning in the line of list2? I filtered out all null values here. The warning states, that in the select method a null value might be dereferenced.

#nullable enable

using System.Collections.Generic;
using System.Linq;

namespace TestNamespace
{
    public class Test
    {
        public Test()
        {
            List<string?> testList = new List<string?>()
            {
                "hallo",
                null
            };

            IEnumerable<string> list2 = testList.Where(x => x != null).Select(x => x.Replace("A", "")); // warning
            IEnumerable<string> list3 = testList.Where(x => x != null).Select(x => x != null ? x.Replace("A", "") : ""); // no warning
        }
    }
}

This is the warning I get in the line of list2: Warning about nullable type

In the line of list3 no warning is issued, but the check in the Select-Statement will always be pointless.

Upvotes: 3

Views: 1723

Answers (3)

Joel Coehoorn
Joel Coehoorn

Reputation: 415735

You get a warning because the type in the enumerable is still the nullable string?.

I suppose it's possible another thread changes the hallo entry to null during the enumeration, but more likely the compiler is just not sophisticated enough to understand you have filtered out any possible null values ahead of time.

You can use .Cast<string>() after filtering out the null values to change the type in the enumerable, or you can use a null-forgiving operator to remove the warning.


For fun, I also wrote this:

public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> items)
{
    foreach(var item in items) 
    {
        if (item is object)
        {
           yield return item;
        }
    }
}

See it work here:

https://dotnetfiddle.net/F8iQ0I

Upvotes: 6

ShubhamWagh
ShubhamWagh

Reputation: 645

Even though you using the Where condition to filter, the Select statement stands alone.

The source type for the select statement is still IEnumerable<string?> hence the warning.

Example

For your reference.

As for the second scenario, In this case, No warning because of this

This set of warnings alerts you that you're dereferencing a variable whose null-state is maybe-null.

We know for sure that x won't be null because of the x != null in Select.

Upvotes: 1

Endi
Endi

Reputation: 17

Try to declare List<string> and then in Where clasue (x => !string.IsNullOrEmpty(x))

Upvotes: -1

Related Questions