关于c#:使方法全部为静态类


Making Methods All Static in Class

我的同事根据我的一个类(它是一个实例类)告诉我,如果您的类中没有字段(支持字段),只需使类中的所有方法都是静态的,或者使类成为单例的,这样您就不必使用关键字new来调用这个bl类中的方法。

我想这是常见的良好做法?基本面向对象编程?我只是想看看人们对此的看法。

我想基本上他是说,因为没有状态,不需要方法是实例方法。

在这种情况下,我不确定是否每次都让它成为一个单独的选项……这是某种模式还是他给我的好建议?

这是我要讨论的类(请不要在这个线程中重新发布任何代码,这是私有的):http://www.elbalazo.net/post/class.txt


调用new和构造类引用几乎没有什么缺点,特别是在类没有状态的情况下。.NET中的分配速度很快,因此我不会单独使用它作为类是静态的理由。

通常,如果类没有特定的上下文,我觉得类应该是静态的——如果您只是将类用作"实用程序"方法或非上下文特定操作的占位符,那么作为静态类是有意义的。

如果该类对上下文和具体意义有特定的需求,那么它可能不能证明是静态的,即使它没有状态(尽管这很少见)。有时类的用途是由其引用本身定义的,它提供了一种没有任何局部变量的"状态"(引用本身)。

也就是说,静态类和单例类有很大的区别。单例是一种不同的动物-当需要一个实例(但只有一个实例)来创建类时,您需要使用它。在单例中存在状态,但您使用此模式强制只存在状态的一个副本。这有一个非常不同的含义,我强烈建议避免使用单例来防止需要"呼叫新的"。


类何时应该是静态的没有绝对规则。它可能没有状态,但您可能需要它来引用相等或锁定。当它们的目的适合时,类应该是静态的,将其作为静态类实现。在这种情况下,你不应该遵循严格而快速的规则;使用你"感觉"是正确的。

没有状态使它成为静态的候选者,但是在任意地重构它之前,先看看它的用途。


仅缺少状态是没有理由使方法成为静态的。在很多情况下,无状态类仍应具有实例方法。例如,每当需要在例程之间传递某些逻辑的特定实现时,使用具有实例方法的类就容易得多,因为它允许我们使用接口:

1
2
3
4
interface IConnectionProvider
{
    object GetConnectedObject();
}

我们可以有十几个以上的实现,并将它们传递到需要IConnectionProvider的例程中。在这种情况下,静态是一种非常笨拙的选择。

使用new在无状态类中使用方法没有任何错误。


只要您不需要从类中创建任何抽象,那么静态方法就可以了。如果您的类需要被模拟或实现任何类型的接口,那么最好将该类设置为单例,因为您不能在类上模拟静态方法。可以让singleton实现一个接口,并可以从singleton继承实例方法,而不能继承静态方法。

我们通常使用单例方法而不是静态方法来方便地抽象类。这在单元测试中帮助了很多次,因为我们遇到了一些场景,我们希望模拟一些东西,并且可以很容易地做到,因为该行为是作为单例上的实例方法实现的。


实用程序类通常由不需要状态的独立方法组成。在这种情况下,最好将这些方法设置为静态。您也可以使类成为静态的,因此它不能被实例化。

使用C 3,您还可以利用扩展方法,这将使用这些方法扩展其他类。注意,在这种情况下,需要使类成为静态的。

1
2
3
4
5
6
7
public static class MathUtil
{
    public static float Clamp(this float value, float min, float max)
    {
        return Math.Min(max, Math.Max(min, value));
    }
}

用途:

1
2
float f = ...;
f.Clamp(0,1);


静态类、静态方法和单例类是三个不同的概念。静态类和静态方法通常用于实现严格的实用程序类,或者使它们无状态化,从而保证线程的安全和当前的可用性。

静态类不需要是单例类。singleton意味着类只有一个实例,否则它是可实例化的。它最常用于封装真正单个资源实例(如单个数据库池或单个打印机)的物理世界表示。

回到你同事的建议上来——我倾向于同意这是一个合理的建议。如果方法可以是静态的,则不需要实例化类。它使调用方代码更可读,调用的方法更容易使用。


确保您有充分的理由使类成为静态的。

根据框架设计指南:

Static classes should be used only as
supporting classes for the
object-oriented core of the framework.

DO NOT treat static classes as a miscellaneous bucket.

There should be a clear charter for
the class.


大多数情况下,可以将类设置为静态。但一个更好的问题是,为什么你有一个没有州的班级?

很少有无状态类是良好设计的实例。但是无状态类会破坏面向对象的设计。它们通常是功能分解的回归(在面向对象技术流行之前,所有的流行)。在使类成为静态类之前,请先问问自己,它正在处理的数据是否应包含在类中,或者实用程序类中的所有功能是否不应在可能存在或可能不存在的其他类之间分解。


对于一个没有成员的非静态类,我可以考虑很多原因。首先,它可以实现一个接口,并提供/增强另一个接口的行为。其次,它可能具有允许定制的虚拟或抽象方法。基本上,使用"静态"方法是最糟糕的过程编程,与面向对象设计相反。

尽管如此,通常小型实用程序的例程最好是用过程实现来完成的,因此如果它有意义的话,不要回避。考虑一下string.isNullOrEmpty()这是一个很好的过程静态例程的例子,它提供了不作为方法的好处。(好处是它还可以检查字符串是否为空)

围栏另一侧的另一个例子是序列化例程。每次发言不需要任何成员。假设它有两种方法:写入(流、对象)和对象读取(流)。这不需要是一个对象,静态方法就足够了;但是,作为一个对象或接口是有意义的。作为一个对象,我可以重写它的行为,或者稍后更改它的实现,以便它缓存关于它序列化的对象类型的信息。让它成为一个对象,从你开始,不要限制你自己。


听起来你在说一个严格意义上的实用程序类,在这种情况下,没有理由有单独的实例。

使这些实用方法静态化。如果愿意,可以将类作为常规对象(以便将来添加实例方法/状态信息)。