什么时候在实例类中使用私有静态方法是有意义的?

本文关键字:静态方法 有意义 实例 什么时候 | 更新日期: 2023-09-27 18:18:31

我继承了一些常规类的代码,其中包含一些私有静态方法。代码(伪代码)如下所示

public class Animal
{
    private string typeOfAnimal;
    public Animal(string typeOfAnimal)
    {
        this.typeOfAnimal = typeOfAnimal;
    }
    public void MakeSound()
    {
        var sound = Animal.GetSound(typeOfAnimal);
        // Make use of sound here       
    }
    private static string GetSound(string typeOfAnimal)
    {
        if(typeOfAnimal  == "dog")
            return "bark";
        else if(typeOfAnimal == "cat")
            return "mjau";
    }
}

与使GetSound成为常规实例方法相比,这样做有什么好处吗?

什么时候在实例类中使用私有静态方法是有意义的?

静态方法有一些非常小的性能差异,我认为这实际上是SO家伙利用的东西。此外,由于关键字的含义,将方法设置为静态可以略微提高可读性。

我的看法通常是可读性。在这种情况下,有两个不同之处:实例vs静态,公共vs私有。两者本质上都不比另一种更有益,好处只取决于预期用途。在你的例子中,它没有作为公共方法的价值,也不是该类型的公共API的一部分,所以你把它设为私有,并且不想改变实例状态,所以你把它设为静态。

默认情况下,ReSharper会突出显示可以设置为静态的方法

如果您的私有方法不使用任何实例对象,为了获得更好的性能和可读性,建议将其标记为静态方法。

事实上,如果这些方法没有被标记为private,代码分析中将显示以下警告。

CA1822:将成员标记为static

从链接中提取-

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

这个设计看起来很糟糕。getSound不应该是静态的,而应该在每个继承类中实现。

当实例状态与动作本身没有关系时,

使用静态方法。

在这种情况下,

存在一个关系。实例状态(类型)在运行时完成

我会写:

public abstract class Animal {
    public abstract string GetSound();
}
public class Dog:Animal{
    public string GetSound(){return "bark";}
}
public class Cat:Animal{
    public string GetSound(){return "mjau";}
}