4

通过今天的一些随机对象创建,我发现了一个简洁的Dictionary<K, V>. 以下赋值是编译器快捷方式还是Dictionary<string, string>.

IDictionary<string, string> items = { { "item1key", "item1value" } };

查看源代码,Dictionary<K, V>我没有看到任何关于它是如何工作的东西。为此类 dot 实现所有接口不允许我执行类似的操作。为什么我们可以为字典而不是另一种类型。例如,编译器或语言特性如何知道第一项是键,第二项是值。或者更具体的,同样的语法不能用于List<string>

List<string> items = { "item1" };

所以第一个是有效的,为什么?

我不一定要尝试复制这一点,而是很好奇为什么会这样。在这种情况下,是什么让字典特别?

有效的例子

public class Button
{
    public string Title { get; set; }
    public ButtonType Type { get; set; }
    public IDictionary<string, string> Items { get; set; }
    public bool RequiresSelected { get; set; }
}

var buttons = new List<Button>
    {
        new Button { 
            Items = {
                        {"button1", "Button 1"},
                        {"button2", "Button 2"},
                        {"button3", "Button 3"},
                    }, 
            Title = "3 Buttons", 
            Type = ButtonType.DropDown 
        }
    };
4

2 回答 2

7

您显示的语法在 C# 中无效。你需要:

IDictionary<string, string> items = new Dictionary<string, string>
    { { "item1key", "item1value" } };

那时它只是一个普通的集合初始化器,所以列表等效项是:

List<string> items = new List<string> { "item1" };

编辑:让我们看看我的编辑能不能打败你的。我的猜测是你已经看到了类似的东西:

var foo = new Foo {
    SomeDictionaryProperty = { 
         { "item1key", "item1value" }
    }
};

这是一个嵌入式集合初始化器,也可以用于列表。它不是创建一个字典,而是添加到现有字典。上面的代码等价于:

var tmp = new Foo();
tmp.SomeDictionaryProperty.Add("item1key", "item1value");
var foo = tmp;

它工作的另一个例子:

var form = new Form {
    Controls = { new Label { Text = "Foo"}, new Label { Text = "Bar" } }
};

有关详细信息,请参阅 C# 4 规范(对象初始化器)的第 7.6.10.2 节。重要的是:

member-initializer:
    identifier   =   initializer-value

initializer-value:
    expression
    object-or-collection-initializer

因此,您可以将属性初始化为特定值(在这种情况下将使用 setter)通过对象/集合初始化程序,在这种情况下将使用属性的getter,然后 setter 或 Add 方法将用于对象/集合初始化器的主体。

于 2012-05-03T20:46:48.323 回答
2

这是C#编译器的一个特性,字典并不特殊:任何支持的集合Add都可以用这种方式初始化。详细信息在C# Language Specification 4.0的第 7.6.10.3 节中。

应用集合初始值设定项的集合对象必须是实现 System.Collections.IEnumerable 的类型,否则会发生编译时错误。对于按顺序指定的每个元素,集合初始值设定项在目标对象上调用 Add 方法,并将元素初始值设定项的表达式列表作为参数列表,对每个调用应用正常的重载决议。因此,集合对象必须包含适用于每个元素初始值设定项的 Add 方法。

于 2012-05-03T20:51:34.427 回答