为什么C#3.0对象初始化器构造函数括号是可选的?

时间:2010-09-07 17:20:59

标签: c# syntax types language-design initializer

似乎C#3.0对象初始化器语法允许在存在无参数构造函数时排除构造函数中的打开/关闭括号对。例如:

var x = new XTypeName { PropA = value, PropB = value };

相反:

var x = new XTypeName() { PropA = value, PropB = value };

我很好奇为什么构造函数打开/关闭括号对在XTypeName之后是可选的?

5 个答案:

答案 0 :(得分:138)

答案 1 :(得分:10)

因为这就是语言的指定方式。它们没有增加任何价值,为什么要包括它们呢?

它与非隐式类型数组

非常相似
var a = new[] { 1, 10, 100, 1000 };            // int[]
var b = new[] { 1, 1.5, 2, 2.5 };            // double[]
var c = new[] { "hello", null, "world" };      // string[]
var d = new[] { 1, "one", 2, "two" };         // Error

参考:http://msdn.microsoft.com/en-us/library/ms364047%28VS.80%29.aspx

答案 2 :(得分:7)

这样做是为了简化对象的构造。语言设计者没有(据我所知)明确说明为什么他们觉得这很有用,尽管在C# Version 3.0 Specification page中明确提到:

  

对象创建表达式可以省略构造函数参数列表并括起括号,前提是它包含对象或集合初始值设定项。省略构造函数参数列表并括起括号等同于指定空参数列表。

我认为他们觉得在这个例子中,为了显示开发者意图,没有必要使用括号,因为对象初始化器显示了构造和设置对象属性的意图。

答案 3 :(得分:4)

在您的第一个示例中,编译器推断您正在调用默认构造函数(C#3.0语言规范声明如果未提供括号,则调用默认构造函数。)

在第二个中,您显式调用默认构造函数。

您还可以使用该语法在将值显式传递给构造函数时设置属性。如果您有以下类定义:

public class SomeTest
{
    public string Value { get; private set; }
    public string AnotherValue { get; set; }
    public string YetAnotherValue { get; set;}

    public SomeTest() { }

    public SomeTest(string value)
    {
        Value = value;
    }
}

这三个陈述都是有效的:

var obj = new SomeTest { AnotherValue = "Hello", YetAnotherValue = "World" };
var obj = new SomeTest() { AnotherValue = "Hello", YetAnotherValue = "World"};
var obj = new SomeTest("Hello") { AnotherValue = "World", YetAnotherValue = "!"};

答案 4 :(得分:1)

我不是Eric Lippert,所以我不能肯定地说,但我认为这是因为编译器不需要空括号来推断初始化构造。因此它变成了冗余信息,而不是必需的。