调用类的非静态方法

时间:2010-07-30 14:12:00

标签: c#

以下列方式调用类的非静态方法的优点(如果有的话)是上行或下行(性能,良好的编码实践,垃圾收集等):

new ClassA().MethodA(param1, param2);

与更“传统”的

方式相反
ClassA classA = new ClassA();
classA.MethodA(param1, param2);

任何想法都会非常感激。

10 个答案:

答案 0 :(得分:10)

<强>编码
至于编码实践,第二个选项更好,其中对象首先存储在变量中。使其更好的原因是您可以根据使用它的上下文命名对象。例如:

var pendingUserForRegistration = new User();

<强>性能
至于性能,第一个选项可能稍好一些,因为它直接从堆栈中使用对象并在局部变量中跳过对象的存储。从IL的方法可以看出:

IL of first:

.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 of second:

.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 

这通常是一个很小的性能开销,很难找到解决实际性能问题的案例。


底线
由于此处代码增益的可维护性大于性能增益,因此最好将对象存储在具有有意义名称的变量中。

答案 1 :(得分:3)

根本没有任何区别。只是在这种情况下静态方法可能更合适。

答案 2 :(得分:2)

后端没有区别。在CIL中,它将创建一个ClassA对象,然后调用该方法。这两段代码都转换为相同的CIL,因此根本没有性能差异。

答案 3 :(得分:1)

如果您不打算将ClassA用于其他任何事情,那么new ClassA().MethodA(param1, param2);就可以了。否则,您应该使用更传统的实例化ClassA classA = new ClassA();

答案 4 :(得分:1)

我看不出它们之间有什么区别。但是,如果ClassA实现IDisposable两者都是个坏主意。

答案 5 :(得分:1)

两者完全相同。实际上,编译器很有可能为每个生成相同的IL。

传统方法这是调试的一个优势,如果您确定问题是在ctor或MethodA中;或者如果MethodA改变了对象,你需要检查它。

答案 6 :(得分:0)

一般来说,当我不需要课程“知道”任何东西时,我会使用静态方法;当类需要知道自身及其自身状态时,我使用实例方法。

或多或少。

答案 7 :(得分:0)

我发现自己问你为什么要在通话网站上这样做。如果你无法绕过它,最好用静态方法包装new ClassA().MethodA(a,b)以避免在呼叫站点发出代码噪音。

答案 8 :(得分:0)

他们是完全相同的。第一种方法意味着少一行代码。如果有人需要修改代码以开始调用MethodB,那么第二种方法会更好。

答案 9 :(得分:0)

你的第一种方法需要实例化一个ClassA实例(除了将类定义加载到内存中,如果到目前为止从未使用过该类)。第二种方法避免了这个额外的对象实例化以及类的后续垃圾收集。

如果这种情况不时发生而不是数百万次,我就不会打扰了。但是,如果您不需要访问任何类实例方法或属性,那么实现静态方法将是一种更干净的设计。

有时会使用稍微不同的方法:假设ClassA在其构造函数中需要一个参数,该参数可能初始化一个私有字段或一个属于您的方法将使用的属性。在这种情况下,第一种方法是必须的:

new ClassA(param0).MethodA(param1, param2);

但是 - 即使这样,该方法也可以重新定义以获取其他参数。