在查看项目源代码时,我偶然发现了一种方法,想知道一件事。从性能/内存/编译器的角度来看,以下两种方法是否完全相同?

public static string Foo(string inputVar)
{
    string bar = DoSomething(inputVar);
    return bar;
}

public static string Foo(string inputVar)
{
    return DoSomething(inputVar);
}

返回变量是由编译器自动创建的吗?

最佳答案

使用IL Disassembler(包含在.NET SDK/VS中),您可以查看由编译器生成的IL。该代码是使用VS2013(不是Roslyn)生成的。

最上面的一个给出以下IL:

.method public hidebysig static string  Foo(string inputVar) cil managed
{
  // Code size       14 (0xe)
  .maxstack  1
  .locals init ([0] string bar,
           [1] string CS$1$0000)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  call       string TestIL.Program::DoSomething(string)
  IL_0007:  stloc.0
  IL_0008:  ldloc.0
  IL_0009:  stloc.1
  IL_000a:  br.s       IL_000c
  IL_000c:  ldloc.1
  IL_000d:  ret
} // end of method Program::Foo

第二个:
.method public hidebysig static string  Foo(string inputVar) cil managed
{
  // Code size       12 (0xc)
  .maxstack  1
  .locals init ([0] string CS$1$0000)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  call       string TestIL.Program::DoSomething(string)
  IL_0007:  stloc.0
  IL_0008:  br.s       IL_000a
  IL_000a:  ldloc.0
  IL_000b:  ret
} // end of method Program::Foo

区别似乎是第一个在方法locals表中创建了一个额外的条目。如果不通过JIT编译器对其进行优化,我将不知道。

要回答这个问题:不,在这种情况下编译器似乎不会自动生成局部变量,但在更高级的情况下,它可能会自动生成(例如返回x *(y + z))。

编辑:如果您打开“优化代码”,则更加清晰:
.method public hidebysig static string  Foo(string inputVar) cil managed
{
  // Code size       9 (0x9)
  .maxstack  1
  .locals init ([0] string bar)
  IL_0000:  ldarg.0
  IL_0001:  call       string TestIL.Program::DoSomething(string)
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ret
} // end of method Program::Foo

.method public hidebysig static string  Foo(string inputVar) cil managed
{
  // Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       string TestIL.Program::DoSomething(string)
  IL_0006:  ret
} // end of method Program::Foo

关于c# - 编译器会自动创建返回变量吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24426223/

10-14 09:46