C#新语句之后的括号是什么?
给定下面的代码, position0
的初始化方式和position0
的初始化方式之间有什么区别? 他们是否等同? 如果不是,有什么区别?
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; }
对象和集合初始化器,用于初始化对象上的字段。
http://msdn.microsoft.com/en-us/library/bb384062.aspx
他们产生几乎相当于IL。 Jon Skeet对实际情况有了答案。
它们并不完全相同 ,至less在一般情况下不是。 使用对象初始值设定项的代码更接近于:
Position tmp = new Position(); tmp.x = 3; tmp.y = 4; Position position1 = tmp;
换句话说,对variables的赋值只在属性设置后才会发生。 现在,在你声明一个新的局部variables的情况下,这实际上并不重要,编译器可能会优化你的第一个表单。 但从逻辑上讲,这很重要。 考虑:
Position p1 = new Position { x = 10, y = 20 }; p1 = new Position { x = p1.y, y = p1.x };
如果p1.x
p1
的分配,那么对于p1.x
和p1.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;
编辑:我刚刚意识到,你使用的是一个结构,而不是一个类。 这可能会造成一些微妙的差异…但你几乎肯定不应该使用可变的结构来开始:)
这是一个对象初始化程序,只是允许您在单个expression式中分配值。 最重要的是,这也适用于匿名types(否则不可变)的LINQ中。 addi项目也有类似的集合初始化语法到新的集合。
请注意,有一个微妙的时间问题,可以是有用的; 初始化的赋值/添加全部在variables赋值之前发生,这可以帮助阻止其他线程看到不完整的对象。 否则,您将需要一个额外的variables来达到相同的结果。
你的两个代码示例将生成相同的IL。 (至less在发布版本中)
忘记所有的IL的东西,它只是速记符号。 你在做什么是这样的:
一个。 在一种情况下,你明确地使用默认的构造函数,然后设置两个属性。
湾 另一方面,你正在使用新的初始化语法,它隐式地使编译器做你所做的事情。
IL尽pipe如此,他们将为你实现同样的目标。
这些完全相同。 编译器实际上只是将第一个版本转换成第二个版本。
两者之间唯一的区别在于,在第一种情况下,你可以做很好的事情,比如把初始化版本传给一个方法:
DoSomethingWithPoint(new Position() { x=3, y=4 });
这是比第二个初始化示例更多的代码行。
除了一个比另一个更容易阅读外,它们是相同的。
当你想把新对象传递给别的地方时,也要考虑这种情况:
var aList = new List<Position>(); aList.Add( new Position() { x=3, y=4 } );