方法内联如何在C#中使用自动属性?

时间:2011-03-27 22:20:25

标签: c# .net compiler-construction jit

我正在阅读Effective C# (Second Edition),它谈到方法内联

我理解这个原则,但是根据书中的两个例子,我看不出它是如何工作的。这本书说:

  

内联意味着将函数体替换为函数调用。

足够公平,所以如果我有一个方法,并且它的调用:

public string SayHiTo(string name)
{
    return "Hi " + name;
}

public void Welcome()
{
    var msg = SayHiTo("Sergi");
}

JIT编译器可能(会?)将其内联到:

public void Welcome()
{
    var msg = "Hi " + "Sergi";
}

现在,有了这两个例子(逐字逐句):

示例1

// readonly name property
public string Name { get; private set; }

// access:
string val = Obj.Name;

示例2

string val = "Default Name";
if(Obj != null)
    val = Obj.Name;

这本书提到了代码,但没有进一步讨论它们如何被内联。 JIT编译器如何内联这两个示例?

3 个答案:

答案 0 :(得分:6)

自动属性是字段支持属性的语法糖。

属性是setter和/或getter方法的语法糖。

因此,您提供的代码或多或少等同于:

private string _name;
public string get_Name()
{
  return _name;
}
private void set_Name(string value)
{
  _name = value;
}

然后string val = Obj.Name等同于string val = Obj.get_Name(),可以内联到string val = Obj._name

同样代码

string val = "Default Name";
if(Obj != null)
  val = Obj.Name;

相当于:

string val = "Default Name";
if(Obj != null)
  val = Obj.get_Name();

可以内联到:

string val = "Default Name";
if(Obj != null)
  val = Obj._name;

请注意privatepublic适用于编译,而不适用于执行,因此虽然支持字段是私有的,但会使Obj._name在相关类之外非法,允许使用内联生成的等效代码。

答案 1 :(得分:4)

假设说,这里内联将打开由编译器自动生成的get_Name()的主体,它只返回一个私有支持字段。它可能看起来像这样:

string val = Obj.k__BackingField;

答案 2 :(得分:2)

在可访问性检查之后进行内联,因此它可以通过简单的源代码替换来优化代码。