将类实例化为变量与否

时间:2014-05-16 16:57:08

标签: c#

这两种编写功能相当的代码的方式在性能方面是否存在差异?

选项1:

SomeObjecModel TheObjectModel = new SomeObjectModel();
return TheObjectModel.SomeMethod();

选项2:

return  new SomeObjectModel().SomeMethod();

在选项1中,对象被实例化为变量,而在选项2中,没有变量。如果有任何不同,我只是好奇。

感谢。

6 个答案:

答案 0 :(得分:7)

可能没有可衡量的差异。在这两种情况下,花费的绝大部分时间都将实例化对象,以及执行方法。

使用您认为更易读(因此可维护)的版本。

答案 1 :(得分:5)

有WAS - 在断点的情况下,您无法在调试器中看到该值(因为您只能在返回之前设置断点。

因此,我经常使用第一种语法在返回时设置断点并查看值。实际上我甚至会将SomeMethod()调用放入变量中,原因完全相同。

自VS 2013 Update 1或2以来,调试器中显式提供了返回值,因此第一种语法没有实际意义。

此处描述了更新:

http://blogs.msdn.com/b/visualstudioalm/archive/2013/06/27/seeing-function-return-values-in-the-debugger-in-visual-studio-2013.aspx

答案 2 :(得分:3)

生成的IL代码存在差异:

Option1:
IL_0000:  newobj      UserQuery+SomeObjectModel..ctor
IL_0005:  stloc.0     // TheObjectModel
IL_0006:  ldloc.0     // TheObjectModel
IL_0007:  callvirt    UserQuery+SomeObjectModel.SomeMethod
IL_000C:  ret         

Option2:
IL_0000:  newobj      UserQuery+SomeObjectModel..ctor
IL_0005:  call        UserQuery+SomeObjectModel.SomeMethod
IL_000A:  ret       

(在LinqPad中编译并启用了优化)

然而,它不太可能在运行时产生明显的差异。

答案 3 :(得分:2)

无论哪种方式,您都在创建变量。一个是内联完成的。我会更担心这个变量是否需要处理掉。如果是这样,我宁愿看到所有内容都包含在“使用”声明中。

答案 4 :(得分:0)

这两种编写代码的方法没有区别。在第一个选项中,GC将在范围之后收集变量。您选择编写代码的样式并不重要,编译器会从较高级别转换并编译为较低级别的代码。

例如:Yoy可以使用Delegate代替Action,两者都提供相同的功能,但编码风格不同。因此编译器总是将此Action(高级)语句转换为Delegate(低级别)

答案 5 :(得分:0)

不会有性能差异。因为如果你检查了IL代码,它会在创建后为构造函数命名。无论如何,你应该更喜欢哪一个更具可读性。

Option1:
IL_0000:  newobj      UserQuery+SomeObjectModel..ctor
IL_0005:  stloc.0     // TheObjectModel
IL_0006:  ldloc.0     // TheObjectModel
IL_0007:  callvirt    UserQuery+SomeObjectModel.SomeMethod
IL_000C:  ret         

Option2:
IL_0000:  newobj      UserQuery+SomeObjectModel..ctor
IL_0005:  call        UserQuery+SomeObjectModel.SomeMethod
IL_000A:  ret  

在使用callvirt之前,可以在类的null实例上调用方法。为了避免空调用,在第一个选项中创建了callvirt。