ReSharper抱怨方法可以是静态的,但不是
为什么ReSharper抱怨当一个方法可以变成静态的,但不是?
是因为只有一个静态方法的实例被创build(在types上),从而节省性能?
我觉得这个评论非常有用,因为它指出了两件重要的事情:
-
这让我问自己,这个问题的方法究竟是否应该是这个types的一部分。 由于它不使用任何实例数据,所以至less应该考虑是否可以将其移到自己的types。 它是types的一个组成部分,还是真的是一个通用的实用方法?
-
如果将方法保留在特定的types上是有意义的,那么编译器会为静态方法发出不同的代码,这会带来潜在的性能提升。
从FxCop文档的相同的警告(强调增加):
“不访问实例数据或调用实例方法的成员可以被标记为静态(在Visual Basic中为Shared)。将这些方法标记为静态后,编译器将向这些成员发出非虚拟调用站点。发出非虚拟调用站点将阻止每次调用的运行时检查,以确保当前的对象指针是非空的, 这可以导致对性能敏感的代码的性能提升,在某些情况下,无法访问当前对象实例代表正确性问题“。
在这个问题上非常好的辩论(SO) 。 我现在处于静态静态化的阵营。 我相信这是因为为什么会有一个实例方法不使用任何实例数据的概念。 这真的是一个实例方法,还是实际上是一个类方法?
如果声明为静态,则不需要创build类(0)的实例来使用该方法…可以节省构build处理,堆空间和cpu周期所需的cpu周期堆…
另外,你的问题,就像它写的那样
“…只有一个静态方法的实例被创build(在types上)…”
意味着对于一个实例方法,对于所创build的类的每个实例都重复该方法的代码。 那是不正确的。 无论您为任何types创build了多less个实例,这些方法的代码都只会被加载到内存中一次。 存储在每个实例的堆上的对象只存储types的“状态”(非静态字段和一些misc跟踪variables)。
这不是一个投诉,这只是build议。
对于静态方法,您不必将“this”推到函数的堆栈上。 这是更便宜的另一个原因。
对我来说,这个ReSharperbuild议的最大好处(可以设置为警告,build议或提示)。 这是否鼓励我尽可能地使静态方法尽可能多。 这是一件好事,因为静态方法对它所属的类没有直接的依赖关系。 这意味着它可以很容易地作为一个静态成员移动到另一个类。
另一个在ReSharper中使用静态技巧的巧妙方法是通过使用“Make Method Static”重构来使一组相关的方法成为静态的。 这会将一些依赖关系移到方法参数中。 当您稍后查看这组方法时,您可能会发现它们都访问特定types的特定对象。 然后,您可以使用“非静态方法”进行重构,并将该对象指定为新的指针。 这将你的方法转移到另一个类中。
由此:
internal class ClassA { public ClassB Property { get; set; } public int Method() { var classB = Property; return classB.Property1 + classB.Property2; } } internal class ClassB { public int Property1 { get; set; } public int Property2 { get; set; } }
对此:
public static int Method(ClassB property) { var classB = property; return classB.Property1 + classB.Property2; }
对此:
internal class ClassA { public ClassB Property { get; set; } } internal class ClassB { public int Property1 { get; set; } public int Property2 { get; set; } public int Method() { return Property1 + Property2; } }
静态在第一次使用时被实例化并保留在内存中。 如果不再使用,可能是个问题。 静态更难testing(moke等…)。