未初始化变量

时间:2018-08-24 14:15:17

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

我刚遇到一个案例,其中Visual Studio告诉我我的代码可能会导致访问未初始化的变量,但是布尔逻辑规则规定这在这里是不可能的。

我简化了代码以可视化问题,在这种情况下,该问题出现在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的错误消息。

备注:设置括号不会更改任何内容,如果也没有,则将三元运算符解析为完整的功能。

这是已知行为还是错误?

编辑:只是为了澄清,我确实知道如何解决该问题。遇到此错误令我有些惊讶,因为根据布尔逻辑,描述的问题(访问未初始化的x)将永远不会发生。

编辑:如果使用完整则不会改变问题:

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;
    }
}

1 个答案:

答案 0 :(得分:2)

问题是此行中的x

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

由于您具有null传播运算符(?.),因此,xdictionary时将不会分配null。您必须将x作为var上方的一个独立变量,并使用默认值。

MyType x = MyType.None;

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

静态编译器不够聪明,无法弄清楚null传播运算符将导致该表达式始终返回false(因此,从未使用x)。不仅如此,它只是尽可能地对待该语句。

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

相关问题