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?