为什么ReSharper会在方法变为静态时抱怨,但不是?
是因为只创建了静态方法的一个实例(在类型上),从而节省了性能吗?
答案 0 :(得分:101)
我发现该评论非常有用,因为它指出了两个重要的事情:
这让我问自己是否有方法 问题实际上应该是一部分 类型与否。因为它不使用 任何实例数据,你应该在 至少考虑是否可以移动 自己的类型。它是不可或缺的一部分 这种类型,还是真的一般 目的实用方法?
如果确实有意义的话 关于具体类型的方法,有 潜在的性能提升 编译器会发出不同的代码 对于静态方法。
答案 1 :(得分:25)
从FxCop文档中获取相同的警告(强调添加):
“不访问实例数据或调用实例方法的成员可以标记为静态(在Visual Basic中共享)。将方法标记为静态后,编译器将向这些成员发出非虚拟调用站点。 - 虚拟调用站点将阻止在运行时检查每个调用,以确保当前对象指针非空。这可以为性能敏感的代码带来可测量的性能提升。在某些情况下,无法访问当前对象实例表示正确性问题。“
答案 2 :(得分:6)
Very good debate on that subject here (SO)。我在if-it-can-make-static-static-make-it-static的阵营中。我相信这是因为人们为什么会有一个不使用任何实例数据的实例方法的概念。在这种情况下,它真的是一个实例方法,还是实际上是一个类方法?
答案 3 :(得分:5)
如果声明为静态,则需要创建类的无(零)实例以使用该方法...在回收时,垃圾收集器可以节省构造处理,堆空间和cpu周期所需的cpu周期来自堆的对象......
另外,你的问题,正如它写的那样
“...只创建一个静态方法实例(在类型上)......”
意味着对于实例方法,对于创建的类的每个实例重复该方法的代码。事实并非如此。无论您为任何类型创建了多少个实例,方法的代码只会加载到内存中一次。存储在堆上的每个实例的对象只存储类型的“State”,(非静态字段和一些misc跟踪变量)。
答案 4 :(得分:3)
这不是抱怨,只是建议。
答案 5 :(得分:1)
对于静态方法,您不必将“this”推入函数的堆栈。这是它更便宜的另一个原因。
答案 6 :(得分:1)
对我来说,这个ReSharper建议的最大好处是(您可以将其设置为警告,建议或提示)。是否鼓励我尽可能多地制作静态方法。这是一件好事,因为静态方法没有直接依赖它所属的类。这意味着它可以很容易地作为静态成员移动到另一个类。
ReSharper中静态的另一个巧妙技巧是使用“Make Method Static”重构使一组相关方法静态化。这会将一些依赖项移动到方法参数中。稍后查看这组方法时,您可能会发现它们都访问特定类型的特定对象。然后,您可以使用“Make method non-static”重构,并将该对象指定为新的 this 指针。这会将您的方法移动到另一个类中。
由此:
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;
}
}
答案 7 :(得分:0)
静态在首次使用时被实例化并将保留在内存中。 如果它不再使用,可能是一个问题。 静态更难测试(moke等......)。