对不起标题,这很难说.请看我的例子.
GetUser1和GetUser2之间有什么区别吗?
class Program { static void Main(string[] args) { GetUser1(); GetUser2(); } private static User GetUser1() { return new User { Name = "Hello" }; } private static User GetUser2() { User user = new User { Name = "Hello" }; return user; } } public class User { public string Name { get; set; } }
我的一个朋友说; 没有区别.
但我这么说; 两种方法之间存在差异.GetUser2正在创建一个不必要的新对象.并且GetUser2具有轻微(非常小的)性能错误,因为您正在创建一个新对象......这是什么真相?我该如何研究这个话题?
更新
非常感谢您的回答...所以我继续问;
如果GetUser1和GetUser2之间没有区别,为什么roslyn会像这样编译代码(链接);
private static User GetUser1() { return new User { Name = "Hello" }; }
Yuval Itzcha.. 8
在发布模式下编译时没有区别.如果在调试模式下查看发出的IL ,您会注意到在返回对象之前存储和加载变量的附加stloc/ldloc
指令形式的细微差别.
如果查看生成的编译器代码,您将得到两个相同的结果:
private static void Main(string[] args) { Program.GetUser1(); Program.GetUser2(); } private static User GetUser1() { return new User { Name = "Hello" }; } private static User GetUser2() { return new User { Name = "Hello" }; }
并为两者生成的IL代码:
.method private hidebysig static class User GetUser1 () cil managed { // Method begins at RVA 0x2068 // Code size 17 (0x11) .maxstack 8 IL_0000: newobj instance void User::.ctor() IL_0005: dup IL_0006: ldstr "Hello" IL_000b: callvirt instance void User::set_Name(string) IL_0010: ret } // end of method Program::GetUser1 .method private hidebysig static class User GetUser2 () cil managed { // Method begins at RVA 0x2068 // Code size 17 (0x11) .maxstack 8 IL_0000: newobj instance void User::.ctor() IL_0005: dup IL_0006: ldstr "Hello" IL_000b: callvirt instance void User::set_Name(string) IL_0010: ret } // end of method Program::GetUser2
Jon Hanna.. 5
在没有抖动优化的情况下,调试版本之间存在细微差别,因为冗余不会被删除,因此您可以更轻松地检查调试器中的值.
发布版本将删除它,抖动优化也可以这样做,因此在调试情况之外,两者是相同的.
在发布模式下编译时没有区别.如果在调试模式下查看发出的IL ,您会注意到在返回对象之前存储和加载变量的附加stloc/ldloc
指令形式的细微差别.
如果查看生成的编译器代码,您将得到两个相同的结果:
private static void Main(string[] args) { Program.GetUser1(); Program.GetUser2(); } private static User GetUser1() { return new User { Name = "Hello" }; } private static User GetUser2() { return new User { Name = "Hello" }; }
并为两者生成的IL代码:
.method private hidebysig static class User GetUser1 () cil managed { // Method begins at RVA 0x2068 // Code size 17 (0x11) .maxstack 8 IL_0000: newobj instance void User::.ctor() IL_0005: dup IL_0006: ldstr "Hello" IL_000b: callvirt instance void User::set_Name(string) IL_0010: ret } // end of method Program::GetUser1 .method private hidebysig static class User GetUser2 () cil managed { // Method begins at RVA 0x2068 // Code size 17 (0x11) .maxstack 8 IL_0000: newobj instance void User::.ctor() IL_0005: dup IL_0006: ldstr "Hello" IL_000b: callvirt instance void User::set_Name(string) IL_0010: ret } // end of method Program::GetUser2
在没有抖动优化的情况下,调试版本之间存在细微差别,因为冗余不会被删除,因此您可以更轻松地检查调试器中的值.
发布版本将删除它,抖动优化也可以这样做,因此在调试情况之外,两者是相同的.