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?