c# - 未初始化变量的不正确编译器错误使用

标签 c# compiler-errors visual-studio-2017

我刚刚遇到一种情况,Visual Studio 告诉我我的代码可能会导致访问未初始化的变量,但 bool 逻辑规则规定这在这里是不可能的。

我简化了代码以可视化问题,在本例中为 x:

static void Main(string[] args)
{
    IDictionary<String, MyType> dictionary = null;
    if (new Random().Next() % 2 == 0)
    {
        dictionary = new Dictionary<string, MyType>();
        dictionary.Add("xyz", MyType.Whatever);
        dictionary.Add("abc", MyType.DontCare);
    }

    var myType = dictionary?.TryGetValue("abc", out var x) ?? false ? x : MyType.None;
}

enum MyType
{
    None,
    Whatever,
    DontCare
}

如果 dictionary 未初始化,则其为 null,从而导致 ?? 将三元运算符计算为 false。这是 x 不会被初始化的唯一情况,但在三元运算符的真实情况下,我仍然收到 x 的错误消息。

备注:设置括号不会改变任何内容,将三元运算符解析为成熟的 if 也不会改变任何内容。

这是已知行为还是错误?

编辑:澄清一下,我确实知道如何解决这个问题。我只是对遇到这个错误感到有点惊讶,因为根据 bool 逻辑,所描述的问题(访问未初始化的x)永远不会发生。

编辑:使用完整的 if 不会改变问题:

static void Main(string[] args)
{
    ...

    MyType myType;
    if (dictionary?.TryGetValue("abc", out var x) ?? false)
    {
        myType = x; // <-- error still occurs here
    }
    else
    {
        myType = MyType.None;
    }
}

最佳答案

问题出在这一行中的x:

var myType = dictionary?.TryGetValue("abc", out var x) ?? false ? x : MyType.None;

由于您有一个空传播运算符 (?.),因此当 dictionarynull< 时,x 将永远不会被赋值。您必须将 x 作为带有默认值的 var 上方的单独变量。

MyType x = MyType.None;

var myType = dictionary?.TryGetValue("abc", out x) ?? false ? x : MyType.None;

静态编译器不够聪明,无法弄清楚空传播运算符将导致该表达式始终返回 false(因此从不使用 x)。并非它只是将语句视为可以。

正如你在C#语言Github页面上看到的,有一个active feature request让编译器计算出空传播运算符的结果。

关于c# - 未初始化变量的不正确编译器错误使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52006392/

相关文章:

c# - 帮助合并 XML 数据

c# - Lambda 表达式中 SQL WHERE 的等效项是什么?

compilation - javassist编译错误没有这样的类

xaml - Visual Studio 2017 XAML 验证中的 Xamarin 表单

c# - 仅更新 C# 中日期时间对象中的日期

mongodb - 在ubuntu 10.04上编译MongoDB r2.0.2报错

ios - libcrypto 和 libGoogleAdMobAds 中的重复符号 _MD5

c# - 有时我可以编辑并继续,有时我不能在 Visual Studio 2017 中

visual-studio-2015 - 我可以在 Visual Studio 2012/2013/2015/2017/2019 中录制/播放宏吗?

c# - 带有嵌套模型类的 Razor View