【问题标题】:How does method inlining work for auto-properties in C#?方法内联如何用于 C# 中的自动属性?
【发布时间】:2011-03-27 22:20:24
【问题描述】:

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

我了解原理,但根据书中的 2 个示例,我看不出它是如何工作的。书上说:

内联意味着用函数体代替函数调用。

很公平,所以如果我有一个方法及其调用:

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 编译器如何内联这两个示例?

【问题讨论】:

  • 这个问题目前非常广泛,回答以下问题会有所帮助:说明结果内联的书是什么?为什么你认为它不起作用?
  • 编译器是指JITer编译器?
  • @earlNameless, @lukas - 这本书提到了这两个例子,并没有进一步说明 如何 它将被内联,因此我的问题。是的,我的意思是 JIT 编译器。我已经更新了我的问题以明确这些要点,谢谢。

标签: c# .net compiler-construction jit


【解决方案1】:

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

属性是 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;

Is 等价于:

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

可以内联到:

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

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

【讨论】:

    【解决方案2】:

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

    string val = Obj.k__BackingField;
    

    【讨论】:

    • 确实如此。当然,在实践中,C# 编译器不执行任何内联,而是将其推迟到 JIT。在 JIT 级别,方法调用和属性访问之间不再有区别——两者都可以类似地内联。
    • @Hans 我不知道在这种情况下它是否真的会这样做,所以这对我来说是假设的。
    【解决方案3】:

    内联发生在可访问性检查之后,因此它可以以您无法通过简单的源代码替换的方式优化代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 2018-07-13
      • 2019-12-07
      相关资源
      最近更新 更多