为什么在字典中使用隐式集合初始化程序会导致C#中的运行时错误?

时间:2018-03-23 12:28:43

标签: c#

我有一个具有以下特征的异步方法:

public async Task UpdateMerchantAttributes(UpdateMerchantRequestModel model). 

该模型只有一个属性:

public Dictionary<string, string> Attributes { get; set; }

有一段时间我用以下方式在测试中调用它:

await client.UpdateMerchantAttributes(new UpdateMerchantRequestModel { Attributes = 
    {
        {"businessType", "0"}
    }
});

这编译得很好,但在该行的运行时导致NullReferenceException。我对此感到困惑,因为client不是null,并且该行中没有引用任何其他内容(或者看起来一目了然)。然后我尝试添加一个显式的Dictionary声明,如下所示:

await client.UpdateMerchantAttributes(new UpdateMerchantRequestModel { Attributes =
    new Dictionary<string, string>
    {
        {"businessType", "0"}
    }
});

现在好转。这是我的错误,但如果它是编译错误而不是运行时空引用异常,那么这个错误将花费我更少的时间。所以我很好奇,为什么会这样呢?编译器是否认为我试图定义dynamic并以某种方式解析为null

1 个答案:

答案 0 :(得分:7)

第一种形式:

Attributes = 
    {
        {"businessType", "0"}
    }
}
对于.Add(key, value)

syntactic sugar。就这些。它并不关心创建字典(因此,实际上,您正在添加null字典)。

你的第二种形式是解决它的一种方式。另一种更加防弹的方式(因为它可以保护你免受第一种形式的侵害)是使用@ MarcGravell的建议:

public Dictionary<string, string> Attributes
    { get; } = new Dictionary<string,string>(); // set; after the get; is also OK

或在构造函数中填充Attributes