C# 直接在返回代码上声明和初始化有什么区别吗?

C# 直接在返回代码上声明和初始化有什么区别吗?,c#,C#,以下两者之间有什么区别吗 public CustomObject MyMethod() { var myObject = new CustomObject(); return myObject } public int MyIntMethod() { var myInt = 1; return myInt; } 为此: public CustomObject MyMethod() { return new CustomObject(); } p

以下两者之间有什么区别吗

public CustomObject MyMethod() 
{
    var myObject = new CustomObject();
    return myObject
}

public int MyIntMethod() 
{
    var myInt = 1;
    return myInt;
}
为此:

public CustomObject MyMethod() 
{
    return new CustomObject();
}

public int MyIntMethod() 
{
    return 1;
}

编译器是否做了一些不同的事情?像空检查之类的吗?

编译器会自动更新:(编译时没有优化,有优化,编译后的代码是相同的,谢谢您的评论。):

VS

第一种方法有11个装配说明,第二种方法有9个装配说明。有更多的指针内存操作

编译器是否做了一些不同的事情?例如空检查或 像这样的

这取决于您是否启用了优化。编译器不执行空检查

生产代码通常是在启用优化的情况下编译的,因此如何编写代码并不重要

使用局部变量,您可以得到:

IL_0000:  nop         
IL_0001:  ret         

MyMethod:
IL_0000:  nop         
IL_0001:  newobj      UserQuery+CustomObject..ctor
IL_0006:  stloc.0     // myObject
IL_0007:  ldloc.0     // myObject
IL_0008:  stloc.1     
IL_0009:  br.s        IL_000B
IL_000B:  ldloc.1     
IL_000C:  ret         

MyIntMethod:
IL_0000:  nop         
IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     // myInt
IL_0003:  ldloc.0     // myInt
IL_0004:  stloc.1     
IL_0005:  br.s        IL_0007
IL_0007:  ldloc.1     
IL_0008:  ret         

CustomObject..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  nop         
IL_0007:  ret         
IL_0000:  nop         
IL_0001:  ret         

MyMethod:
IL_0000:  nop         
IL_0001:  newobj      UserQuery+CustomObject..ctor
IL_0006:  stloc.0     
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.0     
IL_000A:  ret         

MyIntMethod:
IL_0000:  nop         
IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

CustomObject..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  nop         
IL_0007:  ret         
如果没有局部变量,您将得到:

IL_0000:  nop         
IL_0001:  ret         

MyMethod:
IL_0000:  nop         
IL_0001:  newobj      UserQuery+CustomObject..ctor
IL_0006:  stloc.0     // myObject
IL_0007:  ldloc.0     // myObject
IL_0008:  stloc.1     
IL_0009:  br.s        IL_000B
IL_000B:  ldloc.1     
IL_000C:  ret         

MyIntMethod:
IL_0000:  nop         
IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     // myInt
IL_0003:  ldloc.0     // myInt
IL_0004:  stloc.1     
IL_0005:  br.s        IL_0007
IL_0007:  ldloc.1     
IL_0008:  ret         

CustomObject..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  nop         
IL_0007:  ret         
IL_0000:  nop         
IL_0001:  ret         

MyMethod:
IL_0000:  nop         
IL_0001:  newobj      UserQuery+CustomObject..ctor
IL_0006:  stloc.0     
IL_0007:  br.s        IL_0009
IL_0009:  ldloc.0     
IL_000A:  ret         

MyIntMethod:
IL_0000:  nop         
IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     
IL_0003:  br.s        IL_0005
IL_0005:  ldloc.0     
IL_0006:  ret         

CustomObject..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  nop         
IL_0007:  ret         
通过对编译器进行优化,无论发生什么情况,您都可以得到:

IL_0000:  ret         

MyMethod:
IL_0000:  newobj      UserQuery+CustomObject..ctor
IL_0005:  ret         

MyIntMethod:
IL_0000:  ldc.i4.1    
IL_0001:  ret         

CustomObject..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         

检查这一点的最好方法是编译,查看中间语言代码是编译器生成的。但是我认为A方法声明了两个引用,而B方法只声明了一个引用。因为return是一个引用。正如@Turrican建议的那样-检查使用ILDASM或调试器中的反汇编窗口生成的代码。您可能会发现编译器优化了第一个代码,使其与
C#
中的第二个.Idk相同,但在
Java
中,如果将编译器警告设置为verbose,它会抱怨您的第一个代码块,指出变量
myObject
无效,因此应该直接返回值。这可能同样适用于
C #
,即使编译的代码不同,第一个版本也更容易调试(在更现实的情况下),因为您可以查看方法将要返回的内容。我发现自己经常会失去这种奢侈。除非启用编译器优化,在这种情况下,两种方法都简化为相同的IL。当然,即使没有这样做,抖动也会执行这些优化。当然,除此之外,问题是它们的行为是否不同,而不是它们是否以不同的方式实现相同的功能。这意味着什么?从中可以得出什么结论?请添加一些解释以便于理解