Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中自动属性的方法内联是如何工作的?_C#_.net_Compiler Construction_Jit - Fatal编程技术网

C#中自动属性的方法内联是如何工作的?

C#中自动属性的方法内联是如何工作的?,c#,.net,compiler-construction,jit,C#,.net,Compiler Construction,Jit,我正在阅读,它谈到了方法内联 我理解这个原理,但根据书中的两个例子,我看不出它是如何工作的。书上说: 内联是指用函数体替换函数调用 很公平,所以如果我有一个方法及其调用: public string SayHiTo(string name) { return "Hi " + name; } public void Welcome() { var msg = SayHiTo("Sergi"); } JIT编译器可能(将?)将其内联到: public void Welcome()

我正在阅读,它谈到了方法内联

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

内联是指用函数体替换函数调用

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

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

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

string val = Obj.k__BackingField;

内联在可访问性检查后进行,因此它可以以简单的源代码替换无法实现的方式优化代码。

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

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

因此,您给出的代码大致相当于:

private string _name;
public string get_Name()
{
  return _name;
}
private void set_Name(string value)
{
  _name = value;
}
string val = "Default Name";
if(Obj != null)
  val = Obj.get_Name();
然后
string val=Obj.Name
变为等价于
string val=Obj.get_Name()
,可以内联到
string val=Obj.\u Name

同样,守则

string val = "Default Name";
if(Obj != null)
  val = Obj.Name;
相当于:

private string _name;
public string get_Name()
{
  return _name;
}
private void set_Name(string value)
{
  _name = value;
}
string val = "Default Name";
if(Obj != null)
  val = Obj.get_Name();
它可以内联到:

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

请注意,
private
public
适用于编译,而不是执行,因此,尽管支持字段是private这一事实会使
Obj.\u name
在所讨论的类之外是非法的,但允许内联生成等效代码。

这个问题目前非常广泛,回答以下问题会有所帮助:说明最终内联的书是什么?为什么你认为它不能工作?你说的编译器是指JITer编译器?@earlNameless,@lukas-这本书提到了这两个例子,没有进一步说明它将如何内联,因此我的问题。是的,我指的是JIT编译器。我更新了我的问题,让这些观点更清楚,谢谢你。当然,在实践中,C#编译器不做任何内联,而是延迟到JIT。在JIT级别,方法调用和属性访问之间不再有区别——两者可以类似地内联。@Hans我不知道在这种情况下是否会这样做,所以这对我来说是假设的。