2

While implementing the Nullablility feature in my code, I found out, that ToList() returns a List<T>? instead of a List<T> when the result is declared as var and I was unable to figure out, why that is the case.

Both of these compile without warnings. However the latter is List<int>? instead of List<int>:

List<int> collection1 = Array.Empty<int>().ToList();
var collection2 = Array.Empty<int>().ToList();

Looking at the System.Linq.csproj file on github, I found out that it has

<Nullable>enable</Nullable>

Then looking at the ToList() implementation, I saw that is has the following implementation

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source);
    }

    return source is IIListProvider<TSource> listProvider ? listProvider.ToList() : new List<TSource>(source);
}

Because new List<TSource>(source) is never null, I looked at IIListProvider and found the following declaration:

List<TElement> ToList();

So this does not return List<T>? either.

My question is: Why does the compiler still think, that the ToList() method can return a List<T>? while no code paths can return a nullable value?

Cleptus
  • 3,446
  • 4
  • 28
  • 34
wertzui
  • 5,148
  • 3
  • 31
  • 51
  • 1
    "`ToList()` returns a `List?`" No it doesn't. Can you show a [mcve] showing that it does? Are we thinking about different `ToList()`s? – Sweeper Nov 29 '21 at 08:29
  • I just added an example. It only happens if the result is declared as `var`. – wertzui Nov 29 '21 at 08:30
  • Can you please share code reproducing the issue? I don't get any warnings [here](https://sharplab.io/#v2:D4AQTAjAsAUCAMACEEB0AZAlgOwI4G5YFkIAWQmWAYmwFcAbegQwCN6BTRd7VjogZmRhEAYUQBvWImnJBIUogCyAHgAqAPgAUKfmvWIAzgHtaAJwDG7AJQSpM+3fvSAbk1OIAHogC8hkxfZUVSMsAwAXTSsKJxkUAE5ND1QRE2wwqMcnTIBfWGygA===). And `ToList()` does not return a `List?` (see the [docs](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tolist?view=net-6.0)) – Guru Stron Nov 29 '21 at 08:30
  • And check the inferred type of that `var` declare variable. – Damien_The_Unbeliever Nov 29 '21 at 08:30
  • 1
    See https://stackoverflow.com/q/62685673/15498 – Damien_The_Unbeliever Nov 29 '21 at 08:31
  • That's nothing to do with `ToList`. It's because you are using `var`. – Sweeper Nov 29 '21 at 08:31
  • 1
    @wertzui this is how `var` type inference works. See the [docs](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/var). – Guru Stron Nov 29 '21 at 08:35
  • Thanks Damien_The_Unbeliever and guru-stron. These links provide the answers, I was looking for. – wertzui Nov 29 '21 at 08:49

0 Answers0