我有几个类实际上不需要任何状态。从组织的角度来看,我想把他们放在层次结构中。

但是我似乎不能为静态类声明继承。

就像这样:

public static class Base
{
}

public static class Inherited : Base
{
}

不会起作用。

为什么语言的设计者们拒绝了这种可能性呢?


当前回答

你可以做的一个解决方法是不使用静态类,而是隐藏构造函数,这样类的静态成员是类外部唯一可访问的东西。结果是一个可继承的“静态”类:

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>
{
}

其他回答

您希望通过使用类层次结构实现的目标可以通过命名空间实现。因此,支持名称空间的语言(如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
 {
 }