假设我们有以下模型:
public class Father
{
public Child Child { get; set; }
public string Name { get; set; }
public Father() { }
}
public class Child
{
public Father Father;
public string Name { get; set; }
}
以下实施:
var father = new Father();
father.Name = "Brad";
var child = new Child();
child.Father = father;
child.Name = "Brian";
father.Child = child;
现在我的问题: codesnippet#1相当于codesnippet#2?
或者运行codesnippet#1需要更长的时间吗?
CodeSnippet#1:
var fatherName = father.Child.Father.Child.Father.Child.Name;
CodeSnippet#2:
var fatherName = father.Name;
答案 0 :(得分:4)
C#编译器不优化它,并且只发出调用属性getter的所有操作。
另一方面,JIT编译器可能通过内联这些方法调用做得更好,但无法进一步优化,因为它不了解您的域。优化这可能在理论上导致错误的结果,因为您的对象图可以构造如下:var father = new Father
{
Child = new Child
{
Father = new Father
{
Child = new Child
{
Father = new Father { ... }
}
}
};
或者运行codesnippet#1需要更长的时间吗?
答案是“是”,运行第一个代码片段需要更长的时间,因为C#和JIT都无法优化它。
答案 1 :(得分:2)
不,代码片段不相同。
第一个代码段会像预期的那样为您提供NullReferenceException
,因为您尚未向father.Child
分配任何内容。
即使您确实将子项分配给father.Child
属性,编译器也不能认为值总是保持这种状态,因此它无法优化第一个片段中的任何内容。