C# 字典初始化程序编译不一致

标签 c# compiler-construction syntax dictionary initializer

以下代码可以编译,但会因 NullReferenceException 而失败:

class Test
{
    public Dictionary<string, string> Dictionary { get; set; }
}

static void Main(string[] args)
{
    var x = new Test
    {
        Dictionary =   // fails
        {
            { "key", "value" }, { "key2", "value2" }
        }
    };
}

如果您将标记为“失败”的行替换为以下内容,它将正常工作(如预期):

Dictionary = new Dictionary<string, string> 

失败的语法是否有任何用途——它能否在其他情况下成功使用?或者这是编译器的疏忽?

最佳答案

不,这不是错误...这是您对初始化语法理解的缺陷:)

想法

Dictionary = { ... }

适用于调用者对集合属性具有读取 访问权限但没有写入 访问权限的情况。换句话说,像这样的情况:

class Test
{
    private readonly Dictionary<string, string> dictionary 
        = new Dictionary<string, string>();
    public Dictionary<string, string> Dictionary { get { return dictionary; } }
}

基本上它最终是调用 Add,但没有先创建新集合。所以这段代码:

Test test = new Test { Dictionary = { { "a", "b"}, {"c", "d" } };

相当于:

Test tmp = new Test();
Dictionary<string, string> tmpDictionary = tmp.Dictionary;
tmpDictionary.Add("a", "b");
tmpDictionary.Add("c", "d");
Test test = tmp;

一个很好的例子是 UI 的 Controls 集合。你可以这样做:

Form form = new Form
{
    Controls = 
    {
        new Button { Text = "Hi" }, 
        new TextBox { Text = "There" } 
    }
};

但实际上您无法设置 Controls 属性,因为它是只读的。

关于C# 字典初始化程序编译不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1468067/

相关文章:

c# - 等待杀死进程

c# - SQL Assembly WebResponse和字符串解析非常慢

ubuntu - 将 optirun 和 g++ 设置为编译器以在 Ubuntu 中编译 OpenCL

java - 预期在 int 中使用下划线的分号

c - C 中多个不分隔的相等比较的行为是什么?

c# - 执行 reader 时 count(*) 不起作用

c# - 将 C# ThreadStart 委托(delegate)转换为 VB.NET

compiler-construction - 一种语言的编译器如何用该语言编写?

c++ - 确保 C++ double 为 64 位

javascript - 这个 JavaScript/jQuery 语法如何工作 : (function( window, undefined ) { })(window)?