C#新语句后做什么呢?

时间:2010-10-27 15:07:57

标签: c# .net new-operator

根据下面的代码,初始化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;
}

7 个答案:

答案 0 :(得分:58)

它们不是相当等效 - 至少在一般情况下不是这样。使用对象初始值设定项的代码更接近于此:

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.y的结果为0。而那实际上相当于:

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

答案 1 :(得分:45)

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

http://msdn.microsoft.com/en-us/library/bb384062.aspx

他们产生几乎等效的IL。 Jon Skeet对正在发生的事情有了答案。

答案 2 :(得分:7)

这是一个对象初始化器,只是允许您在单个表达式中指定值。最重要的是,这也适用于LINQ和匿名类型(否则是不可变的)。对于新集合,addi项目也有类似的集合初始化语法。

请注意,有一个微妙的时间问题可能有用;对于初始化者,分配/添加全部在分配变量之前发生,这可以帮助阻止其他线程看到不完整的对象。否则你需要一个额外的变量来实现相同的结果。

答案 3 :(得分:2)

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

答案 4 :(得分:2)

忘记所有IL的东西,它只是简写符号。你在做什么是这样的:

一个。在一种情况下,您明确使用默认构造函数,然后设置两个属性。

湾另一方面,您正在使用新的intializer语法,它隐式地使编译器执行您在执行的操作时执行的操作。

尽管如此,他们会为你做同样的事情。

答案 5 :(得分:1)

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

两者之间的唯一区别是,对于第一个,你可以做很好的,比如将初始化的版本传递给方法:

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

这比第二个初始化示例要多得多。

答案 6 :(得分:1)

它们是等同的,除了一个比另一个更容易阅读。

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

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