对象初始值设定项和构造函数有什么区别?
这两者之间有什么区别,你会在“构造函数”上使用“对象初始值设定项”,反之亦然? 我正在使用C#,如果这很重要。 此外,是特定于C#或.NET的对象初始值设定项方法吗?
对象初始化器被添加到C#3中,以便在使用对象时简化对象的构造。
构造函数运行,给定0个或多个参数,用于在调用方法获得创build对象的句柄之前创build和初始化一个对象。 例如:
MyObject myObjectInstance = new MyObject(param1, param2);
在这种情况下,将使用值param1
和param2
运行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(可设置)属性指定值,当构造函数不提供任何重载初始化某些字段时,这是特别有用的。 请注意,不过,对象初始值设定项只是语法上的糖,编译之后与赋值序列没有什么不同。