用static
多种语言在成员上使用关键字表示您不应创建该类的实例才能访问该成员。但是,我认为没有理由进行整个课堂学习static
。我为什么以及何时上课static
?
上课能给我带来什么好处static
?我的意思是,在声明静态类之后,仍然应该将他/她希望不带实例化即可访问的所有成员也声明为静态。
例如,这意味着Math
可以将类声明为普通(非静态),而不会影响开发人员的编码方式。换句话说,将类设为静态或普通对开发人员而言是透明的。
用static
多种语言在成员上使用关键字表示您不应创建该类的实例才能访问该成员。但是,我认为没有理由进行整个课堂学习static
。我为什么以及何时上课static
?
上课能给我带来什么好处static
?我的意思是,在声明静态类之后,仍然应该将他/她希望不带实例化即可访问的所有成员也声明为静态。
例如,这意味着Math
可以将类声明为普通(非静态),而不会影响开发人员的编码方式。换句话说,将类设为静态或普通对开发人员而言是透明的。
Answers:
它使用户明显知道如何使用该类。例如,编写以下代码完全是胡说八道:
Math m = new Math();
C#不必须禁止这一点,但因为它没有任何意义,还不如告诉用户。某些人(包括我在内)恪守这样的理念:编程语言(和API…)应尽可能地严格限制,以使它们难以被错误使用:只有允许的操作才是有意义且(希望)正确的操作。
sealed
。我承认并非所有人都同意这种观点,但评论并不是讨论此事的好地方。但在的情况下,static
这个问题甚至不构成本身:实例System.Math
将永远是有意义的。
Math
类的所有成员都声明Math
为静态,而没有将类声明为静态,则仍然可以使用它,而无需实例化。
static
。
new Math()
。
StackOverflow对此主题进行了精彩的讨论。为了便于参考,我将代表作者Mark S. Rasmussen复制并粘贴到此处:
我在较早的线程中写了关于静态类的想法:
我曾经喜欢用静态方法填充的实用程序类。他们对辅助方法进行了很好的合并,否则将导致冗余和维护麻烦。它们非常易于使用,无需实例化,无需处理,只是忘了忘了。我想这是我首次尝试创建面向服务的体系结构-许多无状态服务只是完成了工作,而没有其他。但是,随着系统的发展,巨龙将会来临。
多态性
假设我们有一个方法UtilityClass.SomeMethod,它愉快地响起。突然,我们需要稍微更改功能。大多数功能是相同的,但是我们仍然必须更改几个部分。如果不是静态方法,我们可以制作一个派生类并根据需要更改方法的内容。由于它是静态方法,因此不能。当然,如果我们只需要在旧方法之前或之后添加功能,我们可以创建一个新类并在其中调用旧类-但这很麻烦。
界面问题
出于逻辑原因,无法通过接口定义静态方法。而且由于无法覆盖静态方法,因此当需要通过它们的接口传递静态类时,静态类是无用的。这使我们无法将静态类用作策略模式的一部分。我们可能通过传递委托而不是接口来修补一些问题。
测试中
这基本上与上面提到的界面问题并存。由于我们交换实现的能力非常有限,因此我们也很难用测试代码替换生产代码。同样,我们可以将它们包装起来,但是它要求我们更改代码的大部分内容,以便能够接受包装器而不是实际的对象。
福斯特斑点
由于静态方法通常用作实用程序方法,而实用程序方法通常具有不同的用途,因此我们很快就会得到一个充满非一致性功能的大型类-理想情况下,每个类在系统中应具有一个单一的用途。只要他们的目的得到明确定义,我宁愿选择五倍的课程。
参数蠕变
首先,这个可爱又天真的静态方法可能只需要一个参数。随着功能的增长,添加了两个新参数。不久,添加了其他可选参数,因此我们创建了该方法的重载(或仅添加默认值(使用支持它们的语言))。不久,我们有了一个采用10个参数的方法。实际上只需要前三个,参数4-7是可选的。但是,如果指定了参数6,则还必须填写7-9 ...如果我们仅出于执行此静态方法的目的而创建了一个类,则可以通过在构造函数,并允许用户通过属性或方法设置可选值,以同时设置多个相互依赖的值。也,
要求消费者无缘无故地创建类的实例
最常见的论据之一是,为什么要求我们的类的使用者创建一个实例来调用该单一方法,而之后再不使用该实例呢?在大多数语言中,创建类的实例是非常便宜的操作,因此速度不是问题。向消费者添加额外的代码行是为将来可维护性更高的解决方案奠定基础的低成本。最后,如果要避免创建实例,只需创建类的单例包装即可,以方便重用-尽管这确实要求类是无状态的。如果不是无状态的,您仍然可以创建可处理所有内容的静态包装器方法,而从长远来看仍将为您带来所有好处。最后,
只有一个西斯处理绝对
当然,我不喜欢静态方法也有例外。对于静态方法而言,不会造成任何膨胀风险的真正实用程序类是绝佳的案例-以System.Convert为例。如果您的项目是一次性的,对将来的维护没有要求,那么总体架构真的不是很重要-静态还是非静态,都没有关系-但是开发速度确实如此。
标准,标准,标准!
使用实例方法并不妨碍您也使用静态方法,反之亦然。只要差异化背后有其合理性并被标准化即可。没有什么比查看遍布着不同实现方法的业务层更糟糕的了。
我很惊讶没有其他人提到static
类允许扩展方法 -安全地扩展您不拥有的现有类型(包括向接口添加方法定义)。例如,在Scala中是
trait MyFoo {
def foo: Int
def plusFoo(a: Int) = foo + a
}
可以用C#表示为
public interface IMyFoo {
int Foo();
}
public static class MyFooExtensions {
public static int PlusFoo(this IMyFoo f, int a) {
return f.Foo() + a;
}
}
对我来说,静态类(在C#中)有点像调用一个函数。
例如
public static string DoSomething(string DoSomethingWithThisString){}
我传入一个字符串,然后返回一个字符串。一切都包含在该方法中。无法访问成员变量等
老实说,对我而言,它的主要用途是减少代码行:
为什么:
MyClass class = new MyClass();
String s = class.DoSomething("test");
当我可以这样做时:
String s = MyClass.DoSomething("test");
因此,在那些情况下,当我想要做一些不需要类的事情并且意味着更少的键入时,我将使用静态类。
Mark S.点是有效的,但是对我来说,如果我有一些实用方法,就更容易假装我要调用一个函数以将它们引用为一个衬里。
那可能很简单,但这主要是我使用的方式static
。