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。当然,即使没有这样做,抖动也会执行这些优化。当然,除此之外,问题是它们的行为是否不同,而不是它们是否以不同的方式实现相同的功能。这意味着什么?从中可以得出什么结论?请添加一些解释以便于理解