C# new 语句后面的大括号有什么作用?
根据下面的代码,position0
的初始化方式和 position1
的初始化方式有什么区别?它们相等吗?如果不是,有什么区别?
class Program
{
static void Main(string[] args)
{
Position position0 = new Position() { x=3, y=4 };
Position position1 = new Position();
position1.x = 3;
position1.y = 4;
}
}
struct Position
{
public int x, y;
}
Given the code below, what is the difference between the way position0
is initialized and the way position1
is initialized? Are they equivalent? If not, what is the difference?
class Program
{
static void Main(string[] args)
{
Position position0 = new Position() { x=3, y=4 };
Position position1 = new Position();
position1.x = 3;
position1.y = 4;
}
}
struct Position
{
public int x, y;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
它们并不完全等同——至少在一般情况下是这样。使用对象初始值设定项的代码与此更接近:
换句话说,对变量的赋值仅在设置属性之后发生。现在,在您声明一个新的局部变量的情况下,这实际上并不重要,编译器可能会优化您的第一种形式。但从逻辑上讲,这确实很重要。考虑一下:
如果首先对
p1
进行了赋值,那么p1.x
和p1最终都会得到0。 y 。而这实际上相当于:
编辑:我刚刚意识到您使用的是结构而不是类。这可能会产生一些微妙的差异......但你几乎肯定不应该使用可变结构来开始:)
They are not quite equivalent - at least not in the general case. The code using an object initializer is closer to this:
In other words, the assignment to the variable only occurs after the properties have been set. Now in the case where you're declaring a new local variable, that doesn't actually matter, and the compiler may well optimize to your first form. But logically, it does matter. Consider:
If that did the assignment to
p1
first, you'd end up with 0 for bothp1.x
andp1.y
. Whereas that's actually equivalent to:EDIT: I've just realised that you're using a struct rather than a class. That may make some subtle differences... but you almost certainly shouldn't be using a mutable struct to start with :)
对象和集合初始值设定项,用于初始化对象上的字段。
http://msdn.microsoft.com/en-us/library/bb384062.aspx
它们产生几乎相同的IL。乔恩·斯基特对到底发生了什么有了答案。
Object and collection initializers, used to initialize fields on an object.
http://msdn.microsoft.com/en-us/library/bb384062.aspx
They produce nearly equivalent IL. Jon Skeet has the answer on what is really going on.
这是一个对象初始值设定项,仅允许您在单个表达式中分配值。最重要的是,这也适用于 LINQ 内部的匿名类型(否则不可变)。还有一个类似的集合初始化语法,用于将项目添加到新集合中。
请注意,有一个微妙的时间问题可能很有用;使用初始化器,赋值/添加都发生在分配变量之前,这可以帮助阻止其他线程看到不完整的对象。否则,您将需要一个额外的变量来实现相同的结果。
That is an object initialiser, and simply allows you to assign values in a single expression. Most importantly, this also works inside LINQ an for anonymous types (otherwise immutable). There is also a similar collection initialiser syntax for addi items to new collections.
Note that there is a subtle timing issue that can be useful; with initialisers the assignments/adds all happen before the variable is assigned, which can help stop other threads seeing an incomplete object. You would otherwise need an additional variable to achieve the same result.
您的两个代码示例将生成相同的 IL。 (至少在发布版本中)
Your two code samples will generate identical IL. (At least in Release builds)
它们是等效的,只是其中一个比另一个更容易阅读。
还要考虑当您想将新对象传递到其他地方时的情况:
They are equivalent, apart from one being easier to read than the other one.
Also consider the case when you want to pass the new object along to somewhere else:
忘记所有 IL 的东西,它只是速记符号。你正在做的是
:在一种情况下,您显式使用默认构造函数,然后设置这两个属性。
b.另一方面,您正在使用新的初始化器语法,它隐式地使编译器执行您在情况 a 中所做的操作。
尽管 IL 很微妙,但它们将为您实现同样的目标。
Forgetting about all the IL stuff, it is just shorthand notation. What you are doing is this:
a. In one case you are explicitly using the default constructor and then setting the two properties.
b. In the other, you are using the new intializer syntax which implicitly makes the compiler do what you did in case a.
IL subtelties notwithstanding, they will achieve the same thing for you.
这些是完全等价的。编译器实际上只是将第一个版本转换为第二个版本。
两者之间的唯一区别是,对于第一个,您可以做一些不错的事情,例如将初始化版本传递给方法:
这比第二个初始化示例的代码行数要多得多。
These are fully equivalent. The compiler actually just transforms the first version into the second one.
The only difference between the two is that with the first, you can do nice thins, like pass the initialized version to a method:
This is a lot more lines of code than the second initialization example.