5

假设我们有以下模型:

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?

还是运行代码片段#1 需要更长的时间?

代码片段#1:

var fatherName = father.Child.Father.Child.Father.Child.Name;

代码片段#2:

var fatherName = father.Name;
4

2 回答 2

4

C# 编译器不会对此进行优化,只会发出调用属性 getter 的所有操作。

另一方面,JIT 编译器可能会通过内联这些方法调用做得更好,但无法进一步优化它,因为它不了解您的领域。优化这在理论上可能会导致错误的结果,因为您的对象图可以按如下方式构造:

var father = new Father
{
    Child = new Child
    {
        Father = new Father
        {
            Child = new Child
            {
                Father = new Father { ... }
            }
        }
    };

还是运行代码片段#1 需要更长的时间?

答案是“是”,运行第一个代码片段需要更长的时间,因为 C# 和 JIT 都无法优化它。

于 2013-06-27T10:27:57.380 回答
2

不,代码片段不等效。

第一个代码片段会给你一个NullReferenceException正如预期的那样,因为你没有分配任何东西给father.Child.

即使您确实将子项分配给了该father.Child属性,编译器也不能假设这些值将始终保持这种状态,因此它无法优化第一个片段中的任何内容。

于 2013-06-27T10:30:21.367 回答