【问题标题】:Derive a static class in C#在 C# 中派生一个静态类
【发布时间】:2011-03-12 13:27:48
【问题描述】:

我知道,理论上,您不能(也不应该)在 C# 中派生静态类,但我有一个案例我认为我需要它...我想为 A 类定义一些静态常量而且,正如我很快发现的那样,你不能这样做,所以我按照本教程进行操作:http://msdn.microsoft.com/en-us/library/bb397677.aspx

所以,我有一个像这样的静态类:

public static class ClassAConstants
{
    public const string ConstantA = "constant_a";
    public const string ConstantB = "constant_b";
}

然后,我的 B 类扩展了 A 类并添加了一些新的静态常量。我想做的是:

public static class ClassBConstants : ClassAConstants
{
    public const string ConstantC = "constant_c";
    public const string ConstantD = "constant_d";
}

这样,四个常量可以通过 ClassBConstants.ConstantA 或 ClassBConstants.ConstantD 访问。但是,C# 不会让我这样做。

我怎样才能做到这一点?也许解决方案完全不同,我不在乎它是否根本不使用静态常量,只要结果是我想要的。


编辑:

感谢 Amby,我发现常量是隐式静态的,所以我真的不需要创建人工静态类(ClassAConstants 和 ClassBConstants)。解决方案再简单不过了:

public class A
{
    public const string ConstantA = "constant_a";
    public const string ConstantB = "constant_b";

    // ...

}
public class B : A
{
    public const string ConstantC = "constant_c";
    public const string ConstantD= "constant_d";

    // ...

}

使用该代码,我得到了我最初想要的结果。

【问题讨论】:

  • 如果你真的需要一个普通类的静态实例,单例模式会有所帮助
  • ClassBConstants IS-A ClassBConstants?

标签: c# static constants


【解决方案1】:

选择 Singleton 而不是 static 类。 然后,您的课程将受益于非static 课程可用的功能,用户只需进行以下更改:

ClassAConstants.ConstantA ... 到 ... ClassAConstants.Instance.ConstantA

顺便说一句,如果你只对consts 感兴趣,那么下面的代码也可以编译。然后你可以从这些类的实例中访问这些常量,或者直接使用类名(如访问静态成员)。

public class ClassAConstants
{
    public const string ConstantA = "constant_a";
    public const string ConstantB = "constant_b";
}

public class ClassBConstants : ClassAConstants
{
    public const string ConstantC = "constant_c";
    public const string ConstantD = "constant_d";
}

这是可能的,因为consts 隐含为static

ClassAConstants.ConstantA .. 有效。

ClassBConstants.ConstantA .. 有效。

【讨论】:

  • "consts are implicitly static" 好的,这正是我所需要的。如果我在类中声明常量,没有“静态”,它会完全按照我最初想要的方式工作。谢谢!
【解决方案2】:

您不能从静态类派生。

如果这两个类都在您的控制之下,您可以随时合并它们(假设这不会破坏其他人的代码)。

如果它们不是,那么你为什么要给人一种印象,即 B 类包含它实际上没有的功能?

最后,如果你真的很想走这条路,一个选择是将A 类中的静态成员复制/粘贴到B 类中。但就我个人而言,我认为这将是一个糟糕的决定。

【讨论】:

  • @Jon 一个人想要派生一个静态类的原因有很多。如果我有 ConstantsForVersion1 和 ConstantsForVersion2,如果它是超集,我可能想从 V1 派生 V2。作为常量,我可以简单地复制它们,但我可能很懒惰,通常重复相同的代码两次是不好的做法。
  • @xanatos:当然,DRY 很好。但不引入不必要的耦合也很好(随机示例:如果有人更改了V1 的常量怎么办?)。但是 +1 因为你是 CLIPPER 程序员;我在 x86 上的第一语言是 CLIPPER :)
  • @xanatos - 你真的在这里实现了 IS-A 关系吗?推导有什么作用吗?如果您绝对必须使用静态类,在 V2 中,为什么不直接将常量添加到类中呢? V1 是否以某种方式使用 V2 类构建?
  • @Ritch 显然这不是“标准”IS-A 关系,因为您无法实例化静态类。这只是一堆常量/方法。它更像是一个#include "v2.h" 文件,其中#include "v1.h" 使代码更短且更具可读性。如果没有它,您将不得不仔细检查 v2 以确保它是 v1 的超集。
  • @xanatos - 我只需要一个 constants.h。源代码树的版本 1 将具有版本 1 的 constants.h,而版本 2 将具有版本 2。
【解决方案3】:

你可以这样做:

public static class ClassAConstants
{
    public const string ConstantA = "constant_a";
    public const string ConstantB = "constant_b";
}

public static class ClassBConstants
{
    public static string ConstantA
    {
        get { return ClassAConstants.ConstantA; }
    }
    public static string ConstantB
    {
        get { return ClassAConstants.ConstantB; }
    }
    public const string ConstantC = "constant_c";
    public const string ConstantD = "constant_d";
}

但我不认为你真的需要这样做。

【讨论】:

    【解决方案4】:

    您始终可以将您的类声明为普通类(非静态),并使您的公共成员保持静态。

    【讨论】:

      猜你喜欢
      • 2018-01-07
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 2014-04-27
      • 2015-02-01
      • 1970-01-01
      • 2010-11-22
      • 2014-08-12
      相关资源
      最近更新 更多