我有几个类实际上不需要任何状态。从组织的角度来看,我想把他们放在层次结构中。
但是我似乎不能为静态类声明继承。
就像这样:
public static class Base
{
}
public static class Inherited : Base
{
}
不会起作用。
为什么语言的设计者们拒绝了这种可能性呢?
我有几个类实际上不需要任何状态。从组织的角度来看,我想把他们放在层次结构中。
但是我似乎不能为静态类声明继承。
就像这样:
public static class Base
{
}
public static class Inherited : Base
{
}
不会起作用。
为什么语言的设计者们拒绝了这种可能性呢?
当前回答
可以这样考虑:你通过类型名访问静态成员,就像这样:
MyStaticType.MyStaticMember();
如果你要从这个类继承,你必须通过新的类型名来访问它:
MyNewType.MyStaticMember();
因此,在代码中使用时,新项与原始项没有关系。没有办法利用任何继承关系来处理多态性之类的事情。
也许您只是想扩展原始类中的一些项。在这种情况下,没有什么可以阻止您在一个全新的类型中使用原始类型的成员。
也许您希望向现有静态类型添加方法。您已经可以通过扩展方法做到这一点。
也许您希望能够在运行时将静态类型传递给函数,并调用该类型的方法,而不需要确切地知道该方法的功能。在这种情况下,您可以使用接口。
所以,最终你不会从继承静态类中获得任何东西。
其他回答
静态类和类成员用于创建可以在不创建类实例的情况下访问的数据和函数。静态类成员可用于分离独立于任何对象标识的数据和行为:无论对象发生了什么,数据和函数都不会改变。当类中没有依赖于对象标识的数据或行为时,可以使用静态类。
类可以声明为静态的,这表明它只包含静态成员。不能使用new关键字创建静态类的实例。当包含静态类的程序或命名空间被加载时,由. net Framework公共语言运行库(CLR)自动加载静态类。
使用静态类来包含与特定对象不关联的方法。例如,通常需要创建一组不作用于实例数据且与代码中的特定对象不关联的方法。您可以使用静态类来保存这些方法。
以下是静态类的主要特性:
它们只包含静态成员。 它们不能被实例化。 它们是密封的。 它们不能包含实例构造函数(c#编程指南)。
因此,创建静态类基本上与创建只包含静态成员和私有构造函数的类相同。私有构造函数阻止类被实例化。
使用静态类的好处是编译器可以检查以确保没有意外添加实例成员。编译器将保证不能创建该类的实例。
静态类是密封的,因此不能被继承。它们不能从Object以外的任何类继承。静态类不能包含实例构造函数;但是,它们可以有一个静态构造函数。要了解更多信息,请参阅静态构造函数(c#编程指南)。
嗯…如果你只是用静态方法填充非静态类,情况会有很大不同吗?
你可以做的一个解决方法是不使用静态类,而是隐藏构造函数,这样类的静态成员是类外部唯一可访问的东西。结果是一个可继承的“静态”类:
public class TestClass<T>
{
protected TestClass()
{ }
public static T Add(T x, T y)
{
return (dynamic)x + (dynamic)y;
}
}
public class TestClass : TestClass<double>
{
// Inherited classes will also need to have protected constructors to prevent people from creating instances of them.
protected TestClass()
{ }
}
TestClass.Add(3.0, 4.0)
TestClass<int>.Add(3, 4)
// Creating a class instance is not allowed because the constructors are inaccessible.
// new TestClass();
// new TestClass<int>();
不幸的是,由于“by-design”语言限制,我们无法做到:
public static class TestClass<T>
{
public static T Add(T x, T y)
{
return (dynamic)x + (dynamic)y;
}
}
public static class TestClass : TestClass<double>
{
}
引用本文:
This is actually by design. There seems to be no good reason to inherit a static class. It has public static members that you can always access via the class name itself. The only reasons I have seen for inheriting static stuff have been bad ones, such as saving a couple of characters of typing. There may be reason to consider mechanisms to bring static members directly into scope (and we will in fact consider this after the Orcas product cycle), but static class inheritance is not the way to go: It is the wrong mechanism to use, and works only for static members that happen to reside in a static class. (Mads Torgersen, C# Language PM)
来自9频道的其他观点
Inheritance in .NET works only on instance base. Static methods are defined on the type level not on the instance level. That is why overriding doesn't work with static methods/properties/events... Static methods are only held once in memory. There is no virtual table etc. that is created for them. If you invoke an instance method in .NET, you always give it the current instance. This is hidden by the .NET runtime, but it happens. Each instance method has as first argument a pointer (reference) to the object that the method is run on. This doesn't happen with static methods (as they are defined on type level). How should the compiler decide to select the method to invoke? (littleguru)
作为一个有价值的想法,littleuru对这个问题有一个部分的“变通方案”:单例模式。
不能继承静态类的主要原因是它们是抽象且密封的(这也阻止了创建它们的任何实例)。
所以这个:
static class Foo { }
编译到这个IL:
.class private abstract auto ansi sealed beforefieldinit Foo
extends [mscorlib]System.Object
{
}