静态与非静态方法

假设你有一些方法可以在非静态类中做成静态的。
例如:

private double power(double a, double b) { return (Math.Pow(a, b)); } 

你看到从方法签名变成静态的好处吗? 在上面的例子中:

 private static double power(double a, double b) { return (Math.Pow(a, b)); } 

即使有一些性能或内存的增益,编译器是不是会在编译时做一个简单的优化?


编辑:我正在寻找的是通过声明方法静态的好处。 我知道这是常见的做法。 我想了解它背后的逻辑。
当然,这个方法只是一个例子来澄清我的意图。

请注意,编译器甚至不允许以您的名义进行更改,因为它会更改方法的签名。 结果,一些精心制作的reflection(如果你使用的话)可能会停止工作,编译器真的不知道情况是否如此。

按照定义, power是无状态的,对任何封闭类都没有副作用,所以它应该被声明为static

从MSDN的这篇文章进入了一些非静态与静态的性能差异。 这个调用大约比实例化和调用快四倍,但它确实只是一个严格的循环,这是一个性能瓶颈。

如果你声明方法是静态的,应该有一个小小的性能改进,因为编译器会发出一个call IL指令而不是callvirt

但是就像其他人所说的那样,它应该是静态的,因为它与特定的实例无关

你看到从方法签名变成静态的好处吗?

三大好处:

  1. 静态的无状态方法有助于文档和澄清其目的。 否则,人们就会担心这个方法依赖于什么神秘的状态?

  2. 静态方法可以从其他静态代码调用,所以可能更有用。

  3. 静态方法调用比实例调用具有更less的运行时间开销。 编译器不能自动完成这个转换 – 一个原因是因为它会影响null的使用。 即使在方法中没有使用实例状态,也需要在空引用上调用该方法,以使NullReferenceException失败。

对我来说,一个简单的问题是“我是否需要实例化这个对象才能调用这个函数”。 在你的function的情况下,我会说答案是否定的,所以它应该是静态的。 这个方法似乎没有关系到你的对象,所以我再投票静态。

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

编译器可能会考虑内联,因为它“短”的代码,因为它是如此之短,如果这样做,那么可能会优化对未使用的这个参数的任何引用。 但是你不能依赖任何那个。

如果你不需要其他的原因,你仍然需要build立一个对象来调用它,除非你把它设置成静态的,否则就会有更大的开销。

这个方法应该是静态的,因为它不涉及你的类或类的成员。 它只是与这个函数的input一起工作。

也许你可能需要调用它而不创build这个类。 所以如果它是静态的,那么可以,但是如果不是的话,你不能在没有任何类的实例的情况下调用它。


静态方法的优点:

没有必要先创build一个对象。 该方法立即可用。

当具有不依赖于特定对象状态的通用function时,这是一个很好的select。 例如,查看java.util中的Arrays类或Collections类。

静态方法可以对工厂有好处。 把你的要求作为参数传回去,得到一个全新的对象。 看起来不是一个构造函数。

静态方法的缺点:

你没有一个对象实例,所以你只能访问静态成员和你自己的局部variables。 如果你想要一个实例,你可能必须自己创build它。

你可以创build子类,但是一个静态方法不能是抽象的,所以很难将你的实现从调用者中分离出来。


(ps:我不认为编译器会优化,如果它将是静态或不..),但不知道)

我相信编译器不会将其优化为静态方法。 性能提高了,因为指针不需要在运行时检查它是否为空。 看看FXCop规则以供参考。

我希望我们需要定义静态和非静态方法之间的区别。 在这里,我发布了几行简单的代码来概念化的差异。

 public class StaticVsNonStatic { public string NonStaticMethod() //non-static { return "I am the Non-Static Method"; } static public string StaticMethod() //static { return "I am Static Method"; } } 

现在让我们创build一个aspx页面,尝试访问这两个在类中定义的方法。

  public partial class StaticVsNonStatic_StaticVsNonWorkplace : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { StaticVsNonStatic objStaticVsNonStatic = new StaticVsNonStatic(); lblDisplayNS.Text = objStaticVsNonStatic.NonStaticMethod(); //Non Static lblDisplayS.Text = StaticVsNonStatic.StaticMethod(); //Static and called without object } } 

谢谢,请发表您的意见。

最好的问候,Pritom Nandy [孟加拉国]