为什么静态类被认为是“类”和“引用类型”?

我今天一直在思考C#和CIL类型系统,我开始想知道为什么静态类被认为是类。 有很多方法它们不是真正的类:

  • “普通”类可以包含非静态成员,静态类则不能。 在这方面,类比结构更类似于静态类,但结构具有单独的名称。
  • 您可以引用“普通”类的实例,但不能引用静态类(尽管它被视为“引用类型”)。 在这方面,类比接口更类似于静态类,但接口具有单独的名称。
  • 静态类的名称永远不能在类型名称通常适合的任何地方使用:您不能声明此类型的变量,您不能将其用作基类型,并且您不能使用它作为generics类型参数。 在这方面,静态类更像名称空间
  • “普通”类可以实现接口。 再次,这使得类更接近结构而不是静态类。
  • “普通”类可以从另一个类inheritance。

将静态类视为从System.Object派生也是奇怪的。 虽然这允许它们“inheritance”静态方法EqualsReferenceEquals ,但是inheritance的目的是有问题的,因为无论如何你都会在对象上调用这些方法。 C#甚至允许您在静态类上明确指定无用inheritance,但不能在接口或结构上指定无用inheritance,其中对象System.ValueType的隐式派生分别实际上有用

关于features-of-features参数:静态类具有类的特征的子集,但它们也具有结构特征的子集。 所有使类与其他类型不同的东西似乎都不适用于静态类。

关于typeof参数:将静态类转换为新的不同类型并不妨碍它在typeof中使用

鉴于静态类的纯粹奇怪性,以及它们与“普通”类之间的相似性的稀缺性,它们是不是应该被制成一种单独的类型而不是一种特殊的类?

是的,他们很奇怪。 它们确实具有类似于类的行为,例如能够拥有(静态)成员变量,以及使用public / private限制对成员的访问。

我几乎在那里键入“public / protected / private”,但显然受保护没有意义,因为没有静态类的方法inheritance。 我认为这样做的主要原因是因为没有实例,你不能拥有多态性,但这并不是inheritance的唯一原因。 多态性很棒,但有时你只想借用基类的大部分function并添加一些属于你自己的东西。 因此,有时您会看到静态类切换为使用单例模式,这样它就可以利用基类集中的一些函数。 在我看来,这是一个克服这个差距的hacky尝试,它变得令人困惑,并引入了许多不自然的复杂性。 另一个选项是聚合,其中子类方法只是将调用传递给父类方法,但这需要大量代码才能将它们整合在一起,并且它们也不是一个完美的解决方案。

目前,静态类通常仅用作全局方法的替代,即仅提供function而不受任何实例约束的方法。 OO纯粹主义者讨厌任何浮动的自由/全局任何概念,但如果你只是需要function,你也不希望有一个不必要的实例和对象浮动,所以一个静态的“类”提供了一个中间地带妥协,双方都可以同意。

所以是的,静态类很奇怪。 理想情况下,如果它们可以被分解为它们自己的概念,那将是很好的,它提供了从不需要绑定到实例的方法获得的灵活性和轻量级易用性(我们现在使用静态类),并将这些方法分组到容器(我们现在也有),但也提供了定义基础实体的能力,它将从中inheritance方法(这是现在缺少的部分)。 另外,它很棒,它是来自类的独立概念,正是由于你提出的原因,它只是让人感到困惑,因为人们自然希望类是具有可以创建和销毁的属性和方法的实例。

就CLR而言,它是一个类。 它基本上只是C#编译器中的语法糖。

我不认为在这里添加一个不同的名称会有任何好处 – 它们的行为大多类似于只有静态方法且无法构造的类,这通常是当我们从中移动时成为静态类的类C#1到C#2。

请记住,如果你想为它创建一个新名称,这可能意味着一个新的关键字……

你的问题是“我为什么要输入static class X而不是foobar X ”。 答案是,因为程序员已经将“class”这个词与“有人为我写的一堆紧密封装的function”联系起来。 巧合的是,它完全符合静态类的定义。

他们可能会使用名称空间,是的。 这就是C ++中发生的事情。 但是术语“静态类”在这里有一个优势:它意味着一个更小 ,更紧密耦合的function组。 例如,你可以有一个名为Qtboost :: asio的命名空间,但是一个名为StringUtilsKWindowSystem的静态类(从KDE借用一个)。

我不知道这是否有资格作为答案,但我要指出“静态类”更多的是语言概念而不是CLR概念。 从CLR的角度来看,它们只是类,与其他类似。 由语言来强制执行您描述的所有规则。

因此,当前实现的一个优点是它不会进一步增加CLR的复杂性,所有CLR目标语言都必须理解和建模。

当然,它们本可以被分成一种单独的东西。

但是这需要在CLR,BCL以及整个语言团队中进行额外的工作,而我本可以放弃其他更重要的事情。

从纯粹的审美观点来看,我可能会同意你的观点。

好的,这可能是因为历史原因,即他们不想发明新的东西,因为静态类已经存在。

C ++,Pascal(Delphi)和Java都有静态类,这些都是C#所基于的。

静态类和“普通”类(和结构)是可执行代码(成员字段,属性,方法)的容器,它们声明了一个Type 。 如果他们有一个单独的词,那么我们会问相反(“如果他们是如此相似,你为什么不使用kayword类?”)。 我建议“通过C#CLR”,其中很好地解释了类型解析,方法调用等是如何发生的。 它对“两个”类的工作方式相同,只是实例成员为实例对象传入了额外的参数。

类与命名空间不同,因为它们仅用于命名和引用。 它们不会影响类的function。

类也与接口不同,因为接口只是编译时validation工具,并没有自己的function。

在我看来,静态类被认为是因为它们可以嵌入私有字段,公共属性和方法,尽管它们是静态的,并且具有固定的地址位置,其中每个对单例方法或属性的调用都将具有其引用。

结构更像是一种值类型,就像你写的那样:

 var struct1 = new Struct1(); var struct2 = struct1; 

每个属性都将被复制到新的内存位置。 此外,使用结构,您将能够更改struct2.Property1值,而无需在struct1.Property1中更改它。

根据反对意见,类在我理解的引用类型中,就像你写的那样:

 var class1 = new Class1(); var class2 = class1; 

这里,复制了引用。 这意味着当您更改class2.Property1时,同样的属性也将在class1.Property1中更改。 这是因为两个类都指向相同的内存地址。

对于静态类,它们被视为引用类型,就像在方法中更改StaticClass.Property值时,此更改将在引用此类的任何位置填充。 它只有一个内存地址且无法复制,因此当发生另一个方法或属性调用时,此新值将优先于旧值。 静态类可以在整个应用程序中共享,因此在您的应用程序中只存在一个引用。 因此,让他们表现得像一个class级。

一个静态类,即使单例模式不是,我猜,鼓励除了绝对目的,可以像一个类或一个类的实例一样代表一个真实的对象。 然而,由于世界上独一无二的物体似乎很少见,我们并不真正需要它们来代表一个实际物体,而只需要一些逻辑物体,例如工具等,或其他一些其他物品 – 使用对象。

编辑事实上,静态类与类中的类似,在Visual Basic中,没有静态类,只有静态(在Visual Basic中为Shared)成员的类。 唯一要考虑的是使这个类NotInheritable(用C#密封)。 因此,C#提供了一个更隐式的function,允许声明一个类静态,而不是使用一个空的默认构造函数使其密封,等等。这是某种快捷方式或语法糖,就像我们想说的那样。

总而言之,我认为没有任何好处或获得新的关键字。

虽然类类型,值类型和接口在许多方面表现得好像它们在三种不同的事物中,但它们实际上都是使用相同类型的Type对象描述的; 类型的父母确定它是什么类型的东西。 特别是,.NET中的所有类型都是类类型,但以下情况除外:

  • inheritance自null System.Object以外的类型; 那些是接口。

  • inheritance自System.ValueTypeSystem.Enum System.ValueTypeSystem.Enum以外的类型; 那些是价值类型。

  • 一些类型,如指针和byrefs,可以通过Type对象(对于参数类型之类的东西来说是必需的)来识别,但是没有其他类型的成员。

每个具有成员且其父母不满足上述任一标准的类型都被视为一个类。 静态类不是真正的类,因为它们具有任何特定的质量,而是因为它们没有任何质量可以使它们成为其他命名类型的东西,并且称它们为“静态类”似乎比发明其他类更容易描述它们的术语。

静态构造函数怎么样? 我认为这是您比较中需要考虑的另一个重要方面。 类和结构支持它们,但接口和命名空间不支持它们。

构建意味着实例化。 虽然实现可能实际上不会创建静态类的“实例”,但您可以将静态类视为类的单例实例,只能有一个引用(类型名称本身)。 如果你可以inheritance静态类,你就会破坏单例概念。 如果您可以声明该类型的变量,那么当它们不再被引用时,您可能希望它们被垃圾收集器清理。

为什么他们的课程而不是结构? 当我想到结构(值类型)时,我会考虑堆栈上的值。 它们的存在(通常)非常短,并且经常被复制。 这再次打破了上面的单一参考单例概念。