在下面的方式中调用类的非静态方法的优缺点是什么(性能、良好的编码实践、垃圾回收等)(如果有的话):
new ClassA().MethodA(param1, param2);
相较于更“传统”的方式
ClassA classA = new ClassA();
classA.MethodA(param1, param2);
非常感谢您的意见。
在下面的方式中调用类的非静态方法的优缺点是什么(性能、良好的编码实践、垃圾回收等)(如果有的话):
new ClassA().MethodA(param1, param2);
相较于更“传统”的方式
ClassA classA = new ClassA();
classA.MethodA(param1, param2);
非常感谢您的意见。
编程
至于编码练习,第二种选项更好,即首先将对象存储在变量中。使其更好的原因是您可以根据使用它的上下文来命名对象。举个例子:
var pendingUserForRegistration = new User();
性能
就性能而言,第一种选项可能会稍微好一些,因为它直接从堆栈中使用对象,跳过在本地变量中存储对象的步骤。可以从方法的IL代码中看到:
第一种选项的IL代码:
.maxstack 8
L_0000: nop
L_0001: newobj instance void NS.ClassA::.ctor()
L_0006: call instance void MS.ClassA::M()
L_000b: nop
L_000c: ret
第二层IL:
.maxstack 1
.locals init (
[0] class NS.ClassA c)
L_0000: nop
L_0001: newobj instance void NS.ClassA::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: callvirt instance void NS.ClassA::M()
L_000d: nop
L_000e: ret
通常情况下,这只会带来微小的性能开销,很难找到一个真正需要解决性能问题的案例。
底线
由于代码的可维护性优势大于性能优势,因此最好将对象存储在具有有意义名称的变量中。
这并不会有任何区别。只是在这种情况下,静态方法可能更适合。
在后端没有区别。在CIL中,它将创建一个ClassA对象,然后调用方法。这两段代码都翻译成相同的CIL,因此完全没有性能差异。
new ClassA().MethodA(param1, param2);
就可以了。否则,您应该选择更传统的实例化方式ClassA classA = new ClassA();
。我看不出它们之间有任何区别。但是,如果ClassA
实现了IDisposable
接口,那么两者都是不好的选择。
ClassA
实现了IDisposable
接口,当实例不再需要时,应手动或通过using
语句调用Dispose
方法。未这样做可能会导致代码泄漏非托管资源(取决于ClassA
的操作)。 - Fredrik Mörk这两者是完全相同的。实际上,编译器很有可能为它们生成相同的IL代码。
传统方法在调试方面具有优势,如果您确定问题是出现在构造函数还是MethodA中;或者如果MethodA修改了对象并且您需要检查它,则可以使用传统方法。
new ClassA().MethodA(a,b)
包装在一个静态方法中,以避免在调用站点产生代码噪音。它们是相同的。第一种方法意味着少了一行代码。如果有人需要修改代码以开始调用MethodB
,则第二种方法稍微好一些。
你的第一种方法需要实例化ClassA类的一个实例(如果该类从未被使用过,则还需要将类定义加载到内存中)。第二种方法避免了这种额外的对象实例化和随后的垃圾回收。
如果这种情况偶尔发生而不是数百万次,我就不会担心。然而,如果您不需要访问任何类实例方法或属性,则实现静态方法将是更清晰的设计。
有时候会使用稍微不同的方法:假设ClassA在其构造函数中需要一个参数,该参数可能会初始化一个私有字段或属性,而该字段或属性又会被您的方法使用。在这种情况下,第一种方法是必须的:
new ClassA(param0).MethodA(param1, param2);
但是 - 即使如此,该方法也可以重新定义以接受其他参数。