Dictionary.TryGetValue 和可能的“null”警告

Ant*_*Ant 1 c# nullable nullable-reference-types

在这种情况下,我似乎无法理解编译器的警告:

using System;
using System.Collections.Generic;

#nullable enable
                    
public class Program
{
    public static void Main()
    {
        Guid guid = Guid.NewGuid();
        
        Dictionary<Guid, string> d = new();
        
        bool found = d.TryGetValue(guid, out string? str);
        
        if (found is false)
        {
            return;
        }
        
        string s = str; // WARNING: possible null value
    }
}
Run Code Online (Sandbox Code Playgroud)

毕竟,我正在执行found检查并在没有值时返回(例如,当out str值为空时)。另外,out该方法的参数.TryGetValue用 注释[MaybeNullWhen(false)]

感谢您帮助找出我的期望中的错误并修复代码,谢谢。代码在这里

Jon*_*eet 8

基本上,编译器(或语言规范)不够“智能”,无法TryGetValue在使用局部变量时对返回值进行条件处理。

如果您将调用内联到条件TryGetValueif,那就没问题:

if (!d.TryGetValue(guid, out string? str))
{
    return;
}
        
string s = str; // No warning
Run Code Online (Sandbox Code Playgroud)

随着时间的推移,这可能会变得更加复杂,但以万无一失的方式指定此类事情相对困难。

这不仅限于可为 null 的引用类型 - 还有其他情况,从人类的角度来看,逻辑代码没有问题,但编译器会拒绝它。例如:

string text;
bool condition = DateTime.UtcNow.Hour == 5;
if (condition)
{
    text = "hello";
}
if (condition)
{
    Console.WriteLine(text); // Error: use of unassigned local variable
}
Run Code Online (Sandbox Code Playgroud)

我们知道,如果我们进入第二个if语句主体,我们也会进入第一个语句主体,因此text将被分配一个值,但编译器的规则不会尝试足够智能来发现这一点。