当方法可以是静态的时候,ReSharper会抱怨,但不是

And*_*ech 65 c# resharper static-methods

为什么ReSharper会在方法变为静态时抱怨,但不是?

是因为只创建了静态方法的一个实例(在类型上),从而节省了性能?

Bri*_*sen 102

我发现该评论非常有用,因为它指出了两个重要的事情:

  1. 它让我问自己,所讨论的方法是否真的应该是类型的一部分.由于它不使用任何实例数据,因此至少应考虑是否可以将其移动到自己的类型.它是该类型的组成部分,还是真正的通用实用方法?

  2. 如果将方法保持在特定类型上是有意义的,那么可能会有性能提升,因为编译器将为静态方法发出不同的代码.

  • 很好的答案 - 这不仅仅是关于性能.Resharper也为您提供一些设计反馈. (12认同)

ito*_*son 25

从FxCop文档中获取相同的警告(强调添加):

"不访问实例数据或调用实例方法的成员可以标记为静态(在Visual Basic中共享).将方法标记为静态后,编译器将向这些成员发出非虚拟调用站点.发出非虚拟调用站点将阻止在运行时检查每个调用,以确保当前对象指针为非null.这可以为性能敏感的代码带来可测量的性能增益.在某些情况下,访问当前对象实例的失败代表正确性问题. "

  • 这是事实,但忽略了这样一个事实,即你不必创建一个对象来处理方法......如果由于某些其他原因不需要实例,则不必创建对象是一个更大的性能增益. (3认同)
  • 同意,性能提升通常很小(对于大多数非平凡的方法而言都是微不足道的).正确性原因通常更令人担忧 - 如果方法不是特定于实例,则将其标记为静态会清楚地表明这是故意的,如果方法*是*意味着特定于实例,那么警告告诉你,你在实施中犯了一个错误. (2认同)

JP *_*oto 6

关于这个主题的辩论非常好(SO).我在if-it-can-make-static-static-make-it-static的阵营中.我相信这是因为人们为什么会有一个不使用任何实例数据的实例方法的概念.在这种情况下它真的是一个实例方法还是它实际上是一个类方法?


Cha*_*ana 5

如果声明为静态,则需要创建类的无(零)实例以使用该方法...在垃圾收集器从回收对象中保存构造处理,堆空间和cpu循环所需的cpu周期堆...

还有,你写的问题

"...只创建一个静态方法的实例(在类型上)......"

意味着对于实例方法,对于创建的类的每个实例重复该方法的代码.事实并非如此.无论您为任何类型创建了多少个实例,方法的代码只会加载到内存中一次.存储在堆上的每个实例的对象仅存储类型的"状态",(非静态字段和一些misc跟踪变量).