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

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

就像这样:

public static class Base
{
}

public static class Inherited : Base
{
}

不会起作用。

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


当前回答

当我试图对第三方库编写IComparer<T>实现时,我遇到了这个问题,其中T是嵌入在类中的enum,如下所示:

public class TheClass
{
    public enum EnumOfInterest
    {
    }
}

但是因为枚举是在第三方库类中定义的,所以我不能编写比较器,因为下面给出了“不能扩展列表”错误:

public class MyComparer : IComparer<TheClass.EnumOfInterest>
{
}

我甚至没有扩展静态类——我只是实现类中定义的枚举的比较器。

其他回答

您希望通过使用类层次结构实现的目标可以通过命名空间实现。因此,支持名称空间的语言(如c#)将无法实现静态类的类层次结构。因为您不能实例化任何类,所以您所需要的只是通过使用名称空间获得的类定义的分层组织

你可以用合成代替…这将允许您从静态类型访问类对象。但仍然不能实现接口或抽象类

你可以做一些看起来像静态继承的事情。

诀窍是这样的:

public abstract class StaticBase<TSuccessor>
    where TSuccessor : StaticBase<TSuccessor>, new()
{
    protected static readonly TSuccessor Instance = new TSuccessor();
}

然后你可以这样做:

public class Base : StaticBase<Base>
{
    public Base()
    {
    }

    public void MethodA()
    {
    }
}

public class Inherited : Base
{
    private Inherited()
    {
    }

    public new static void MethodA()
    {
        Instance.MethodA();
    }
}

Inherited类本身不是静态的,但是我们不允许创建它。它实际上继承了用于构建Base的静态构造函数,并且Base的所有属性和方法都是静态的。现在要做的唯一一件事就是为需要公开到静态上下文的每个方法和属性制作静态包装器。

它也有缺点,比如需要手动创建静态包装器方法和new关键字。但是这种方法有助于支持一些与静态继承非常相似的东西。

注: 我们使用它来创建已编译查询,这实际上可以用ConcurrentDictionary代替,但是具有线程安全性的静态只读字段就足够了。

嗯…如果你只是用静态方法填充非静态类,情况会有很大不同吗?

虽然可以通过继承的类名访问“继承的”静态成员,但静态成员并不是真正继承的。这就是为什么它们不能是虚拟的或抽象的,也不能被覆盖的部分原因。在你的例子中,如果你声明了一个Base.Method(),编译器无论如何都会将对Inherited.Method()的调用映射回Base.Method()。您也可以显式地调用Base.Method()。您可以编写一个小测试,并使用Reflector查看结果。

所以…如果不能继承静态成员,并且静态类只能包含静态成员,那么继承静态类又有什么用呢?