简体   繁体   English

C#中的构造函数与对象初始值设定项的优先级

[英]Constructor vs Object Initializer Precedence in C#

I've been learning the object initializer in C# recently, but now I'm wondering how it works when it conflicts with the constructor.我最近一直在学习 C# 中的对象初始值设定项,但现在我想知道当它与构造函数冲突时它是如何工作的。

public class A
{
    public bool foo { get; set; }

    public A()
    {
        foo = true;
    }

    public A(bool bar)
    {
        foo = bar;
    }
}

What happens when I try this?当我尝试这个时会发生什么?

public class B
{
    private A a = new A() { foo = false };

    private A b = new A(true) { foo = false };
}

Is a default in the constructor a good way to have a bool that starts true and can be changed?构造函数中的默认值是否是让bool开始为 true 并且可以更改的好方法?

public A(bool bar = true)
{
    foo = bar;
}

From the documentation :文档

The compiler processes object initializers by first accessing the default instance constructor and then processing the member initializations.编译器通过首先访问默认实例构造函数然后处理成员初始化来处理对象初始值设定项。

This means that in the simplest case (named object initialization) it is basically shorthand (or syntactic sugar) for calling the default constructor and then calling the property setter(s).这意味着在最简单的情况下(命名对象初始化),它基本上是调用默认构造函数然后调用属性设置器的简写(或语法糖)。 In the case of anonymous types this kind of initialization is actually required and not mere sugar.在匿名类型的情况下,这种初始化实际上是必需的,而不仅仅是糖。

For the 2nd part of your question: It's more of a matter of style but if you have a crucial property I would not create a constructor with a default value.对于您问题的第二部分:这更多是风格问题,但如果您有一个关键属性,我不会创建具有默认值的构造函数。 Make the client code set the value explicitly.使客户端代码显式设置该值。 I'm also not sure why doing something like this: b = A(true) {foo = false};我也不知道为什么要这样做: b = A(true) {foo = false}; would be a good idea unless you're in a code obfuscation contest.除非您参加代码混淆竞赛,否则这将是一个好主意。

Bit of caution though:不过要小心一点:

... if the default constructor is declared as private in the class, object initializers that require public access will fail. ...如果默认构造函数在类中声明为私有,则需要公共访问的对象初始值设定项将失败。

Object initializers are just syntactic sugar, in your compiled assembly IL they translate into separate statements, check it on ILSpy .对象初始值设定项只是语法糖,在您编译的程序集 IL 中,它们转换为单独的语句,请在ILSpy检查

在此处输入图片说明

The constructor occurs first then the object initializer.构造函数首先出现,然后是对象初始值设定项。 Just remember that只要记住

a = new A() { foo = false };

is same as

var temp = new A();
temp.foo = false;
a = temp;
b = new A(true) {foo = false};

is effectively short for:是有效的缩写:

A temp = new A(true);
temp.foo = false;
A b = temp;

where temp is an otherwise inaccessible variable.其中temp是一个否则无法访问的变量。 The constructor is always executed first, followed by any initialised properties.构造函数总是首先执行,然后是任何初始化的属性。

Essentially what Paul has already linked:基本上保罗已经链接的内容:

From the C# 5 language specification (7.6.10.1)来自C# 5 语言规范(7.6.10.1)

Processing of an object creation expression that includes an object initializer or collection initializer consists of first processing the instance constructor and then processing the member or element initializations specified by the object initializer or collection initializer.包含对象初始值设定项或集合初始值设定项的对象创建表达式的处理包括首先处理实例构造函数,然后处理由对象初始值设定项或集合初始值设定项指定的成员或元素初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM