C# new 语句后面的大括号有什么作用?

发布于 2024-09-29 04:17:13 字数 386 浏览 1 评论 0原文

根据下面的代码,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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

羁客 2024-10-06 04:17:13

它们并不完全等同——至少在一般情况下是这样。使用对象初始值设定项的代码与此更接近:

Position tmp = new Position();
tmp.x = 3;
tmp.y = 4;
Position position1 = tmp;

换句话说,对变量的赋值仅在设置属性之后发生。现在,在您声明一个新的局部变量的情况下,这实际上并不重要,编译器可能会优化您的第一种形式。但从逻辑上讲,这确实很重要。考虑一下:

Position p1 = new Position { x = 10, y = 20 };

p1 = new Position { x = p1.y, y = p1.x };

如果首先p1进行了赋值,那么p1.xp1最终都会得到0。 y 。而这实际上相当于:

Position tmp = new Position();
tmp.x = 10;
tmp.y = 20;
Position p1 = tmp;

tmp = new Position();
tmp.x = p1.y; // 20
tmp.y = p1.x; // 10
p1 = tmp;

编辑:我刚刚意识到您使用的是结构而不是类。这可能会产生一些微妙的差异......但你几乎肯定不应该使用可变结构来开始:)

They are not quite equivalent - at least not in the general case. The code using an object initializer is closer to this:

Position tmp = new Position();
tmp.x = 3;
tmp.y = 4;
Position position1 = tmp;

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:

Position p1 = new Position { x = 10, y = 20 };

p1 = new Position { x = p1.y, y = p1.x };

If that did the assignment to p1 first, you'd end up with 0 for both p1.x and p1.y. Whereas that's actually equivalent to:

Position tmp = new Position();
tmp.x = 10;
tmp.y = 20;
Position p1 = tmp;

tmp = new Position();
tmp.x = p1.y; // 20
tmp.y = p1.x; // 10
p1 = tmp;

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 :)

最冷一天 2024-10-06 04:17:13

对象和集合初始值设定项,用于初始化对象上的字段。

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.

[旋木] 2024-10-06 04:17:13

这是一个对象初始值设定项,仅允许您在单个表达式中分配值。最重要的是,这也适用于 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.

多彩岁月 2024-10-06 04:17:13

您的两个代码示例将生成相同的 IL。 (至少在发布版本中)

Your two code samples will generate identical IL. (At least in Release builds)

多彩岁月 2024-10-06 04:17:13

它们是等效的,只是其中一个比另一个更容易阅读。

还要考虑当您想将新对象传递到其他地方时的情况:

var aList = new List<Position>();
aList.Add( new Position() { x=3, y=4 } );

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:

var aList = new List<Position>();
aList.Add( new Position() { x=3, y=4 } );
绝影如岚 2024-10-06 04:17:13

忘记所有 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.

苏璃陌 2024-10-06 04:17:13

这些是完全等价的。编译器实际上只是将第一个版本转换为第二个版本。

两者之间的唯一区别是,对于第一个,您可以做一些不错的事情,例如将初始化版本传递给方法:

DoSomethingWithPoint(new Position() { x=3, y=4 });

这比第二个初始化示例的代码行数要多得多。

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:

DoSomethingWithPoint(new Position() { x=3, y=4 });

This is a lot more lines of code than the second initialization example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文