C#或JIT编译器是否足够智能来处理这个问题?

时间:2013-06-27 10:21:16

标签: c# optimization compiler-construction

假设我们有以下模型:

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;

2 个答案:

答案 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属性,编译器也不能认为值总是保持这种状态,因此它无法优化第一个片段中的任何内容。