Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IDictionary赋值快捷方式编译器功能还是语言功能?_C#_.net_Compiler Construction - Fatal编程技术网

C# IDictionary赋值快捷方式编译器功能还是语言功能?

C# IDictionary赋值快捷方式编译器功能还是语言功能?,c#,.net,compiler-construction,C#,.net,Compiler Construction,今天,通过一些随机对象的创建,我发现了一个字典的简洁快捷方式。以下赋值是编译器的快捷方式还是字典的功能 IDictionary items={{{“item1key”,“item1value”}; 查看字典的源代码我看不出这是如何工作的。实现这个类的所有接口不允许我执行类似的操作。为什么我们可以为一本字典而不是另一种类型做这件事。例如,编译器或语言功能如何知道第一项是键,第二项是值。或者更具体地说,相同的语法不能用于列表 List items={“item1”}; 那么第一个是有效的,为什么

今天,通过一些随机对象的创建,我发现了一个
字典的简洁快捷方式。以下赋值是编译器的快捷方式还是
字典的功能

IDictionary items={{{“item1key”,“item1value”};
查看
字典的源代码
我看不出这是如何工作的。实现这个类的所有接口不允许我执行类似的操作。为什么我们可以为一本字典而不是另一种类型做这件事。例如,编译器或语言功能如何知道第一项是键,第二项是值。或者更具体地说,相同的语法不能用于
列表

List items={“item1”};
那么第一个是有效的,为什么

我不一定要重复这一点,但我很好奇为什么会是这样。在这种情况下,词典有什么特别之处

有效的例子
公共类按钮
{
公共字符串标题{get;set;}
公共按钮类型{get;set;}
公共IDictionary项{get;set;}
公共bool requireselected{get;set;}
}
var按钮=新列表
{
新按钮{
项目={
{“按钮1”,“按钮1”},
{“按钮2”,“按钮2”},
{“按钮3”,“按钮3”},
}, 
Title=“3个按钮”,
类型=按钮类型下拉列表
}
};

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

IDictionary<string, string> items = new Dictionary<string, string>
    { { "item1key", "item1value" } };
这是一个嵌入式集合初始值设定项,也可以用于列表。它不是在创建新词典,而是在添加现有词典。上述代码相当于:

var tmp = new Foo();
tmp.SomeDictionaryProperty.Add("item1key", "item1value");
var foo = tmp;
it工作的另一个例子:

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方法用于对象/集合初始值设定项的主体。

这是C编译器的一项功能,而且字典也不是特别的:任何支持
Add
的集合都可以用这种方式初始化。详细信息见本手册第7.6.10.3节

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


啊,很有趣。像我的示例那样执行内联操作不会编译-lemme提供了我的实际用法。@BuildStarted:在我的机器上不会,即使使用VS11 beta编译器也不会。请展示一个适合您的简短但完整的程序。@BuildStarted:编辑了我的文章,并猜测您正在做什么:)好的,如果我使用列表类型的方式与使用字典的方式相同,那么它将适用于列表类型。因此,它是一种编译器快捷方式,而不一定是语言本身的一项功能,用于快捷方式赋值。@BuildStarted:它绝对是语言的一项功能。编译器正在实现该语言!如果你是这个意思的话,它本身并不是.NET平台的一个功能。很少有东西是编译器特性而不是语言特性——主要是优化、警告等。感谢语言规范提供的关于满足此要求所需的有用信息。这对我的理解有很大帮助。
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" } }
};
member-initializer:
    identifier   =   initializer-value

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