我正在阅读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编译器如何内联这两个示例?
答案 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;
请注意private
和public
适用于编译,而不适用于执行,因此虽然支持字段是私有的,但会使Obj._name
在相关类之外非法,允许使用内联生成的等效代码。
答案 1 :(得分:4)
假设说,这里内联将打开由编译器自动生成的get_Name()
的主体,它只返回一个私有支持字段。它可能看起来像这样:
string val = Obj.k__BackingField;
答案 2 :(得分:2)
在可访问性检查之后进行内联,因此它可以通过简单的源代码替换来优化代码。