Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.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# C中构造函数与对象初始值设定项的优先级#_C#_Constructor_Object Initializers - Fatal编程技术网

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

C# C中构造函数与对象初始值设定项的优先级#,c#,constructor,object-initializers,C#,Constructor,Object Initializers,最近我一直在学习C#中的对象初始值设定项,但现在我想知道它在与构造函数冲突时是如何工作的 public class A { public bool foo { get; set; } public A() { foo = true; } public A(bool bar) { foo = bar; } } 当我尝试这个时会发生什么 public class B { private A a =

最近我一直在学习C#中的对象初始值设定项,但现在我想知道它在与构造函数冲突时是如何工作的

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

    public A()
    {
        foo = true;
    }

    public A(bool bar)
    {
        foo = bar;
    }
}
当我尝试这个时会发生什么

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

    private A b = new A(true) { foo = false };
}
构造函数中的默认值是一种好方法,可以使
bool
开始为true并且可以更改吗

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

构造函数首先出现,然后是对象初始值设定项。记住这一点

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

var temp = new A();
temp.foo = false;
a = temp;
实际上是以下内容的缩写:

A temp = new A(true);
temp.foo = false;
A b = temp;
其中
temp
是一个无法访问的变量。构造函数总是先执行,然后是任何初始化的属性。

来自:

编译器通过首先访问 默认实例构造函数,然后处理成员 初始化

这意味着在最简单的情况下(命名对象初始化),它基本上是调用默认构造函数然后调用属性设置器的简写(或语法糖)。对于匿名类型,这种初始化实际上是必需的,而不仅仅是糖

对于你问题的第二部分:这更多的是风格问题,但是如果你有一个重要的属性,我不会用默认值创建构造函数。使客户端代码显式设置该值。我也不知道为什么要这样做:
b=A(true){foo=false}将是一个好主意,除非你在一个代码混淆比赛

不过需要注意的是:

。。。如果默认构造函数在类中声明为private, 需要公共访问的对象初始值设定项将失败


基本上保罗已经联系到:

从(7.6.10.1)开始

处理包含对象初始值设定项或集合初始值设定项的对象创建表达式包括:首先处理实例构造函数,然后处理由对象初始值设定项或集合初始值设定项指定的成员或元素初始化


对象初始值设定项只是语法糖,在编译的程序集中,如果它们转换成单独的语句,请检查它


试试你的例子。代码就在那里,只需点击runyes,默认初始值设定项仍然有效,但如果你想要多个参数,你可以忘记的参数只是尾部参数。没错,我在实际项目中使用了更复杂的代码。对不起,我猜“当我做这个的时候会发生什么”这一部分让人觉得我只是在问这个问题。不过,我确实需要一些背景/建议。在上面找不到任何文档。它们不一样<代码>a=新a();a、 foo=假使对象保持半初始化状态。并且使用对象成员将给出意外的结果(它们将使用这些基础类型的默认值,例如布尔成员为false),而不是抛出NullReferenceException。另一方面,使用对象初始值设定项或对象构造函数将确保如果发生异常,该对象将不会被初始化,并且如果我们尝试使用其成员(因为它从未被初始化),将给出NullReferenceException。@WaelAlshabani Yes,创建了一个临时对象,然后在将其引用指定给变量之前将属性设置为该临时对象。是的,如果您的属性可能抛出异常,并且您计划捕获它,并且出于某种原因仍然使用分配给变量的引用,那么这是一个微妙但重要的区别。但这些都不适用于这个确切的例子。但我会更新,让这更清楚。
A temp = new A(true);
temp.foo = false;
A b = temp;