对象初始值设定项和构造函数有什么区别?

这两者之间有什么区别,你会在“构造函数”上使用“对象初始值设定项”,反之亦然? 我正在使用C#,如果这很重要。 此外,是特定于C#或.NET的对象初始值设定项方法吗?

对象初始化器被添加到C#3中,以便在使用对象时简化对象的构造。

构造函数运行,给定0个或多个参数,用于在调用方法获得创build对象的句柄之前创build和初始化一个对象。 例如:

MyObject myObjectInstance = new MyObject(param1, param2); 

在这种情况下,将使用值param1param2运行MyObject的构造函数。 这些都用于在内存中创build新的MyObject 。 创build的对象(使用这些参数进行设置)被返回,并设置为myObjectInstance

一般来说,为了完全设置一个对象,让一个构造函数需要所需的参数被认为是一个好习惯,所以不可能创build一个处于无效状态的对象。

但是,通常可以设置“额外”属性,但不是必需的。 这可以通过重载的构造函数来处理,但会导致大量的构造函数在大多数情况下不一定有用。

这会导致对象初始化器 – 对象初始化器允许您在对象构build完成设置对象的属性或字段,但其他对象之前可以使用它。 例如:

 MyObject myObjectInstance = new MyObject(param1, param2) { MyProperty = someUsefulValue }; 

这将会像你这样做:

 MyObject myObjectInstance = new MyObject(param1, param2); myObjectInstance.MyProperty = someUsefulValue; 

但是,在multithreading环境中,对象初始化器的primefaces性可能是有益的,因为它可以防止对象处于未完全初始化状态(请参阅此答案以获取更多详细信息) – 它可以是null或初始化,就像您所期望的那样。

此外,对象初始化器更易于读取(尤其是当您设置多个值时),所以它们为构造函数提供了与重载相同的好处,而无需使用许多重载,从而使该类的API复杂化。

构造函数是一种定义的方法,它接受指定数量的参数,用于创build和初始化对象。

对象初始化程序是在构造函数之后的对象上运行的代码,可用于将对象上的任意数量的字段简洁地设置为指定的值。 这些字段的设置发生调用构造函数之后

如果构造函数充分设置了对象的初始状态,则可以在没有对象初始值设定项的帮助下使用构造函数。 然而,一个对象初始值设定项必须和一个构造函数一起使用。 该语法需要构造函数的显式或隐式使用(VB.Net和C#)来创build初始对象。 当构造函数没有充分初始化对象以供您使用时,您可以使用对象初始值设定项,并使用一些简单的字段和/或属性设置。

当你这样做

 Person p = new Person { Name = "a", Age = 23 }; 

这是对象初始值设定器实质上所做的事情:

 Person tmp = new Person(); //creates temp object calling default constructor tmp.Name = "a"; tmp.Age = 23; p = tmp; 

现在这样做便于这样的行为。 了解对象初始值设定器如何工作很重要。

如果你的属性必须设置在你的对象上才能正常工作,一种方法是只公开一个构造函数,它需要这些必需的属性作为参数。

在这种情况下,如果不指定那些必需的属性,就不能创build对象。 像这样的东西不能由对象初始值设定项强制执行。

对象初始化器实际上只是一个“语法方便”来缩短初始分配。 不错,但是function上并不相关。

渣子

构造函数是一种方法(可能)接受参数并返回一个类的新实例。 它可能包含初始化逻辑。 下面你可以看到一个构造函数的例子。

 public class Foo { private SomeClass s; public Foo(string s) { s = new SomeClass(s); } } 

现在考虑下面的例子:

 public class Foo { public SomeClass s { get; set; } public Foo() {} } 

您可以使用对象初始值设定项实现与第一个示例中相同的结果,假定您可以使用以下代码访问SomeClass:

 new Foo() { s = new SomeClass(someString) } 

正如你所看到的,一个对象初始值设定项允许你在执行构造的同时为public字段和public(可设置)属性指定值,当构造函数不提供任何重载初始化某些字段时,这是特别有用的。 请注意,不过,对象初始值设定项只是语法上的糖,编译之后与赋值序列没有什么不同。