关于c#:我什么时候应该写静态方法?

When should I write Static Methods?

所以我理解静态方法或字段是什么,我只是想知道什么时候使用它们。也就是说,在编写代码时,设计使用静态方法和字段的好处是什么。

一种常见的模式是将静态方法用作静态工厂,但这同样可以通过重载构造函数来实现。对的?例如:

1
var bmp = System.Drawing.Bitmap.LoadFromFile("Image01.jpg");

至于静态字段,创建singelton对象是否是它们的最佳用途?


静态方法通常用于不需要来自类实例(来自this的)任何数据的操作,并且可以仅使用它们的参数来执行它们的预期目的。一个简单的例子是计算两点之间距离的方法Point::distance(Point a, Point b);,不需要实例。

静态字段在其他常量中很有用,这些常量不会经常更改,并且由类的所有实例使用。


当您使用静态工厂时,它提供了一个更好的意图概念——它还允许您使用具有相同参数类型但含义不同的不同工厂。例如,假设位图有loadfromresource(string)——不可能有两个同时使用string的构造函数。

编辑:来自SteveMegson的评论

A static factory can also return null, and can more easily return an instance that it got from cache. Many of my classes have a static FromId(int) to get an instance from a primary key, returning an existing cached instance if we have one.


我会说,只要函数独立于实例的状态,即不依赖于任何实例字段,就使用静态方法。

一个方法依赖的非本地状态越少,就越容易理解,因此static对于代码的读者来说是一个有用的信号。


我通过记住实例方法在单个对象上/内部工作,而静态方法为类做一些事情来保持清晰。

在loadFromFile()的情况下,您需要一个静态方法,因为如果加载失败,您需要一个空引用-实例还不存在。如果您将它实现为一个构造函数,那么您将不得不在失败时抛出一个异常。

静态的其他好用法:比较(obj a,obj b)、删除(obj a)数据对象(对象不能删除自己,因为它的引用仍然存在),或者静态类用于不能在对象中建模的过程代码。


只要函数不依赖于该类的特定对象,就应该使用静态方法。

添加静态关键字没有坏处:它不会破坏引用它的任何代码。例如,无论您是否有"static"关键字,以下代码都是有效的:

1
2
3
4
5
6
7
8
9
10
class Foo
{
    public Foo(){}
    public static void bar(){}  // valid with or without 'static'
    public void nonStatic(){ bar(); }
}

...
Foo a = new Foo();
a.bar();

所以您应该向任何方法添加"static"。


下面是一些您可能希望何时使用静态方法的示例:

1)当函数不使用任何成员变量时。您不必在这里使用静态方法,但这样做通常会有所帮助。

2)使用工厂方法创建对象时。如果您不知道要提前创建的类型,那么它们是特别必要的:例如

1
2
3
4
5
6
7
8
9
class AbstractClass {
    static createObject(int i) {
        if (i==1) {
           return new ConcreteClass1();
        } else if (i==2) {
           return new ConcreteClass2();
        }
     }
}

3)当您控制或以其他方式跟踪类的实例化数时。单例是最常用的例子。

4)声明常量时。

5)对一个类的多个对象进行操作的操作,例如排序或比较,这些操作不与任何特定实例相关联。

6)当必须在对象的第一个实例化之前进行特殊处理时。


当方法不属于特定对象时,请使用静态方法。

例如,如果您查看.NET框架中的数学类,您将看到所有方法都是静态的。为什么?因为没有必要创建使用方法的对象。为什么要创建Math类,当你想要的只是某个东西的绝对值时?不,那里没有理由这样做,因此,该方法是静态的。

所以当你设计一个课程时,问问自己:

这个方法是属于一个对象,还是类本身?

如果方法修改对象的状态,则它属于对象。如果该方法不修改特定的对象,它很可能是静态的。

另一个例子,假设您想知道一个类中有多少个对象这是创建的(不要问我为什么…)。对于此任务,可以创建静态方法GetNumberOfObjects()(显然您需要一个静态字段,以及构造函数中的一些代码)。为什么我要用静电的,你可以问。好吧,回答上面的问题,你会看到的。方法没有属于任何特定对象。此外,它不修改任何对象。

我希望这是有道理的。


当类的客户端没有要使用的类实例时,可以使用静态方法。例如,单例设计模式用于确保系统中只存在类的一个实例。它要求singleton的构造函数是私有的,这样客户端就不能创建任何实例。

因此,如果无法创建实例,如何访问类的实例方法?通过调用返回类的单例实例的静态方法。

当然,这只是一个场景,但还有许多其他场景。