一尘不染

何时在C#中使用静态类

c#

这个问题已经在这里有了答案

单一方法上课-最佳方法? (14个回答)

5年前关闭。

这是MSDN在“ 何时使用静态类” 下必须说的

static class CompanyInfo
{
    public static string GetCompanyName() { return "CompanyName"; }
    public static string GetCompanyAddress() { return "CompanyAddress";

}
//…
}

对于与特定对象无关的方法,请使用静态类作为组织单位。同样,静态类可以使您的实现更简单,更快捷,因为您不必创建对象来调用其方法。以有意义的方式组织类内部的方法(例如System名称空间中Math类的方法)很有用。

在我看来,该示例似乎并未涵盖静态类的很多可能的使用场景。过去,我已经将静态类用于相关功能的无状态套件,但是仅此而已。那么,在什么情况下(也不应该)将类声明为静态?


阅读 526

收藏
2020-05-19

共1个答案

一尘不染

我在较早的Stack Overflow答案中写下了对静态类的想法: 使用单一方法的类-
最佳方法?

我曾经喜欢用静态方法填充的实用程序类。他们对辅助方法进行了很好的合并,否则将导致冗余和维护麻烦。它们非常易于使用,无需实例化,无需处理,只是忘了忘了。我想这是我第一次尝试创建面向服务的体系结构-
许多无状态服务只是完成了自己的工作而已。但是,随着系统的发展,巨龙将会来临。

多态性

假设我们有一个方法UtilityClass.SomeMethod,它愉快地响起。突然,我们需要稍微更改功能。大多数功能是相同的,但是我们仍然必须更改几个部分。如果不是静态方法,我们可以制作一个派生类并根据需要更改方法的内容。由于它是静态方法,因此不能。当然,如果我们只需要在旧方法之前或之后添加功能,则可以创建一个新类并在其中调用旧类-
但这很麻烦。

界面问题

出于逻辑原因,无法通过接口定义静态方法。而且由于无法覆盖静态方法,因此当需要通过它们的接口传递静态类时,静态类是无用的。这使我们无法将静态类用作策略模式的一部分。我们可以通过传递委托而不是接口来修补一些问题。

测试中

这基本上与上面提到的界面问题并存。由于我们交换实现的能力非常有限,因此我们也很难用测试代码替换生产代码。同样,我们可以将它们包装起来,但是这将要求我们更改代码的大部分内容,以便能够接受包装器而不是实际的对象。

福斯特斑点

由于静态方法通常用作实用程序方法,而实用程序方法通常具有不同的用途,因此我们很快就会得到一个充满非一致性功能的大型类-
理想情况下,每个类在系统中应具有一个单一的用途。只要他们的目的得到明确定义,我宁愿选择五倍的课程。

参数蠕变

首先,这个可爱又天真的静态方法可能只需要一个参数。随着功能的增长,添加了两个新参数。不久便添加了可选的其他参数,因此我们创建了该方法的重载(或仅添加默认值(使用支持它们的语言))。不久,我们有了一个采用10个参数的方法。实际上只需要前三个,参数4-7是可选的。但是,如果指定了参数6,则还必须填写7-9
…如果我们仅出于执行此静态方法的目的而创建了一个类,则可以通过在构造函数,并允许用户通过属性或方法设置可选值,以同时设置多个相互依赖的值。另外,如果一种方法已经发展到如此复杂的程度,

要求消费者无缘无故地创建类的实例

最常见的论据之一是:为什么要求我们的类的使用者创建一个实例来调用该单一方法,而之后却不再使用该实例?在大多数语言中,创建类的实例是非常便宜的操作,因此速度不是问题。向消费者添加额外的代码行是为将来奠定更易于维护的解决方案奠定基础的低成本。最后,如果要避免创建实例,只需创建类的单例包装即可,以方便重用-
尽管这确实要求类是无状态的。如果不是无状态的,您仍然可以创建处理所有内容的静态包装器方法,而从长远来看仍然可以为您带来所有好处。最后,new MyClass();

只有西斯(Sith)处理绝对

当然,我不喜欢静态方法也有例外。真正的实用程序类不会造成任何膨胀的风险,对于静态方法来说就是个很好的例子-
以System.Convert为例。如果您的项目是一次性的,对将来的维护没有要求,那么总体架构真的不是很重要-静态还是非静态,都没有关系-
但是开发速度确实如此。

标准,标准,标准!

使用实例方法并不妨碍您也使用静态方法,反之亦然。只要差异化背后有其合理性并被标准化即可。没有什么比查看遍布着不同实现方法的业务层更糟糕的了。

2020-05-19