dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.08k stars 4.04k forks source link

The tuple encounters a nullable inference error when using the LINQ expression FirstOrDefault #75797

Closed jnzhsh closed 1 week ago

jnzhsh commented 1 week ago

Version Used: Microsoft(R) Visual C# 编译器 版本 4.12.0-1.24379.11 (cf82d399) 版权所有(C) Microsoft Corporation。保留所有权利。 Steps to Reproduce:

  1. see following code
        IEnumerable<(Guid, List<string>)> testCase = new List<(Guid, List<string>)>() { (Guid.Empty, Enumerable.Empty<string>().ToList()) };
        var nullableVeb = testCase.FirstOrDefault(x => x.Item1 == Guid.NewGuid()).Item2;
        Test(nullableVeb);
  2. the nullableVeb should nullable,but IntelliSense show it not null Image

Expected Behavior: nullableVeb may be null here

Actual Behavior: nullableVeb is not null here

chrisoverzero commented 1 week ago

The default value of a type is not always null. The method FirstOrDefault will return the default value of a type when the predicate does not match any element of the collection. The syntax (1, 2) creates a value of type ValueTuple<T1, T2>. The type ValueTuple (and types like it, such as ValueTuple<T1, T2>) is a value type, which means that its default value is not null. This is similar to how default(int) has a value of 0, not a value of null.

int[] collection = [1, 2, 3, 4, 5];
var element = collection.FirstOrDefault(v => v >= 6);

Console.WriteLine(element == null); // ==> False
Console.WriteLine(element == 0);    // ==> True

If "first or null" is the behavior you want, there are packages on NuGet which can provide a FirstOrNull method for you to use.