C# 对象初始值设定项和构造函数之间有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/740658/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the difference between an object initializer and a constructor?
提问by Pete
What are the differences between the two and when would you use an "object initializer" over a "constructor" and vice-versa? I'm working with C#, if that matters. Also, is the object initializer method specific to C# or .NET?
两者之间有什么区别,您何时会在“构造函数”上使用“对象初始值设定项”,反之亦然?如果这很重要,我正在使用 C#。此外,对象初始值设定项方法是否特定于 C# 或 .NET?
采纳答案by Reed Copsey
Object Initializers were something added to C# 3, in order to simplify construction of objects when you're using an object.
对象初始值设定项是添加到 C# 3 的东西,目的是在您使用对象时简化对象的构造。
Constructors run, given 0 or more parameters, and are used to create and initialize an object beforethe calling method gets the handle to the created object. For example:
构造函数运行,给定 0 个或多个参数,并用于在调用方法获取已创建对象的句柄之前创建和初始化对象。例如:
MyObject myObjectInstance = new MyObject(param1, param2);
In this case, the constructor of MyObject
will be run with the values param1
and param2
. These are both used to create the new MyObject
in memory. The created object (which is setup using those parameters) gets returned, and set to myObjectInstance
.
在这种情况下, 的构造函数MyObject
将使用值param1
和运行param2
。这些都用于MyObject
在内存中创建新的。创建的对象(使用这些参数设置)被返回,并设置为myObjectInstance
.
In general, it's considered good practice to have a constructor require the parameters needed in order to completely setup an object, so that it's impossible to create an object in an invalid state.
通常,让构造函数需要所需的参数以完全设置对象被认为是一种很好的做法,这样就不可能在无效状态下创建对象。
However, there are often "extra" properties that could be set, but are not required. This could be handled through overloaded constructors, but leads to having lots of constructors that aren't necessarily useful in the majority of circumstances.
但是,通常可以设置“额外”属性,但不是必需的。这可以通过重载的构造函数来处理,但会导致有很多在大多数情况下不一定有用的构造函数。
This leads to object initializers - An Object Initializer lets you set properties or fields on your object afterit's been constructed, but beforeyou can use it by anything else. For example:
这导致对象初始化-对象初始值设定可让您在对象上设置属性或字段后,它已经建立,但之前,你可以通过任何其他使用它。例如:
MyObject myObjectInstance = new MyObject(param1, param2)
{
MyProperty = someUsefulValue
};
This will behave about the same as if you do this:
这将与您执行此操作的行为大致相同:
MyObject myObjectInstance = new MyObject(param1, param2);
myObjectInstance.MyProperty = someUsefulValue;
However, in multi-threadedenvironments the atomicity of the object initializer may be beneficial, since it prevents the object from being in a not-fully initialized state (see this answerfor more details) - it's either null or initialized like you intended.
但是,在多线程环境中,对象初始值设定项的原子性可能是有益的,因为它可以防止对象处于未完全初始化的状态(有关更多详细信息,请参阅此答案)-它要么为空,要么像您预期的那样初始化。
Also, object initializers are simpler to read (especially when you set multiple values), so they give you the same benefit as many overloads on the constructor, without the need to have many overloads complicating the API for that class.
此外,对象初始值设定项更易于阅读(尤其是当您设置多个值时),因此它们为您提供与构造函数上的许多重载相同的好处,而无需使该类的 API 复杂化的许多重载。
回答by JaredPar
A constructor is a defined method on a type which takes a specified number of parameters and is used to create and initialize an object.
构造函数是在类型上定义的方法,它采用指定数量的参数,用于创建和初始化对象。
An object initializer is code that runs on an object after a constructor and can be used to succinctly set any number of fields on the object to specified values. The setting of these fields occurs afterthe constructor is called.
对象初始值设定项是在构造函数之后在对象上运行的代码,可用于将对象上的任意数量的字段简洁地设置为指定值。这些字段的设置发生在调用构造函数之后。
You would use a constructor without the help of an object initializer if the constructor sufficiently set the initial state of the object. An object initializer however must be used in conjunction with a constructor. The syntax requires the explicit or implicit use (VB.Net and C#) of a constructor to create the initial object. You would use an object initializer when the constructor does not sufficiently initialize the object to your use and a few simple field and/or property sets would.
如果构造函数充分地设置了对象的初始状态,您将在没有对象初始值设定项的帮助下使用构造函数。然而,对象初始值设定项必须与构造函数结合使用。语法要求显式或隐式使用(VB.Net 和 C#)构造函数来创建初始对象。当构造函数没有充分初始化对象以供您使用并且一些简单的字段和/或属性集会时,您将使用对象初始值设定项。
回答by em70
A constructor is a method (possibly) accepting parameters and returning a new instance of a class. It may contain initialization logic. Below you can see an example of a constructor.
构造函数是一种(可能)接受参数并返回类的新实例的方法。它可能包含初始化逻辑。下面你可以看到一个构造函数的例子。
public class Foo
{
private SomeClass s;
public Foo(string s)
{
s = new SomeClass(s);
}
}
Now consider the following example:
现在考虑以下示例:
public class Foo
{
public SomeClass s { get; set; }
public Foo() {}
}
You could achieve the same result as in the first example using an object initializer, assuming that you can access SomeClass, with the following code:
您可以使用对象初始值设定项获得与第一个示例相同的结果,假设您可以使用以下代码访问 SomeClass:
new Foo() { s = new SomeClass(someString) }
As you can see, an object initializer allows you to specify values for public fields and public (settable) properties at the same time construction is performed, and that's especially useful when the constructor doesn't supply any overload initializing certain fields. Please mind, however that object initializers are just syntactic sugar and that after compilation won't really differ from a sequence of assignments.
如您所见,对象初始值设定项允许您在执行构造的同时为公共字段和公共(可设置)属性指定值,这在构造函数不提供任何重载初始化某些字段时特别有用。但是请注意,对象初始值设定项只是语法糖,编译后与一系列赋值并没有真正不同。
回答by marc_s
If you have properties that MUST be set on your object for it to work properly, one way is to expose just a single constructor which requires those mandatory properties as parameters.
如果您必须在对象上设置属性才能使其正常工作,一种方法是仅公开一个构造函数,该构造函数需要这些必需属性作为参数。
In that case, you cannot create your object without specifying those mandatory properties. Something like that cannot be enforced by object initializers.
在这种情况下,您不能在不指定这些必需属性的情况下创建对象。对象初始值设定项无法强制执行此类操作。
Object initializers are really just a "syntax convenience" to shorten initial assignments. Nice, but not really very functionally relevant.
对象初始值设定项实际上只是缩短初始分配的“语法便利”。不错,但在功能上并不是很相关。
Marc
马克
回答by nawfal
When you do
当你做
Person p = new Person { Name = "a", Age = 23 };
this is what an object initializer essentially does:
这就是对象初始值设定项的本质:
Person tmp = new Person(); //creates temp object calling default constructor
tmp.Name = "a";
tmp.Age = 23;
p = tmp;
Now this facilitates behaviour like this. Knowing how object initializers work is important.
现在,这有利于类似行为这样。了解对象初始值设定项的工作方式很重要。
回答by Sharunas Bielskis
Object initializers are especially useful in LINQ query expressions. Query expressions make frequent use of anonymous types, which can only be initialized by using an object initializer, as shown in the code example below:`
对象初始值设定项在 LINQ 查询表达式中特别有用。查询表达式经常使用匿名类型,只能通过使用对象初始值设定项进行初始化,如下面的代码示例所示:`
var orderLineReceiver = new { ReceiverName = "Name Surname", ReceiverAddress = "Some address" };
More about it - Object and collection initializers
关于它的更多信息 -对象和集合初始值设定项
回答by Sharunas Bielskis
Object initializers can be useful to initialize some small collection which can be used for testing purposes in the initial program creation stage. The code example is below:
对象初始化器可用于初始化一些小集合,这些集合可用于在初始程序创建阶段进行测试。代码示例如下:
class Program
{
static void Main(string[] args)
{
List<OrderLine> ordersLines = new List<OrderLine>()
{
new OrderLine {Platform = "AmazonUK", OrderId = "200-2255555-3000012", ItemTitle = "Test product 1"},
new OrderLine {Platform = "AmazonUK", OrderId = "200-2255555-3000013", ItemTitle = "Test product 2"},
new OrderLine {Platform = "AmazonUK", OrderId = "200-2255555-3000013", ItemTitle = "Test product 3"}
};
}
}
class OrderLine
{
public string Platform { get; set; }
public string OrderId { get; set; }
public string ItemTitle { get; set; }
}
Here is the catch. In the above code example isn't included any constructor and it works correctly, but if some constructor with parameters will be included in the OrderLine class as example:
这是问题所在。在上面的代码示例中,没有包含任何构造函数并且它可以正常工作,但是如果某些带有参数的构造函数将包含在 OrderLine 类中作为示例:
public OrderLine(string platform, string orderId, string itemTitle)
{
Platform = platform;
OrderId = orderId;
ItemTitle = itemTitle;
}
The compiler will show error - There is no argument given that corresponds to the required formal parameter…. It can be fixed by including in the OrderLine class explicit default constructor without parameters:
编译器将显示错误 - 没有给出与所需形式参数相对应的参数......。它可以通过在 OrderLine 类中包含不带参数的显式默认构造函数来修复:
public OrderLine() {}