c# - 继承和共享静态字段

标签 c# generics inheritance static

假设我有一个通用抽象类,它提供了一些默认的构造函数功能,这样您就不必在继承类中重复代码:

public abstract class Base<TKey, TValue>
{
    private static readonly IDictionary<TKey, Base<TKey, TValue>> Values = new Dictionary<TKey, Base<TKey, TValue>>();

    public TKey Key { get; private set; }
    public TValue Value { get; private set; }

    protected Base(TKey key, TValue value)
    {
        this.Key = key;
        this.Value = value;

        Values.Add(key, this);
    }
}

现在的问题是,当我编写两个继承类时:

public sealed class One : Base<string, string>
{
    public static readonly One Default = new One("DEF", "Default value");
    public static readonly One Invalid = new One("", "Invalid value");

    private One(string key, string value) : base(key, value) {}
}

public sealed class Two : Base<string, string>
{
    public static readonly Two EU = new Two("EU", "European Union");
    public static readonly Two USA = new Two("", "United States of America");

    private Two(string key, string value) : base(key, value) {}
}

如您所见,这两个实际上是类型安全的枚举。它们仅提供预定义值,不能为任何其他目的实例化。

问题

问题是因为这两个继承类都使用相同的泛型,基类是 Base<string, string> .泛型类和静态字段的工作方式是为每个泛型类型(或多个泛型的组合)创建一个新的静态字段。

在我的例子中,组合是 string, string这就是为什么只有 一个基类静态字段 并且它包含 4 个值,而不是有 两个静态字段,每个静态字段有 2 个值。

我如何克服这个问题并将它们分开,同时仍将此功能保留在基类上,这样我就不会重复我的代码?

将字段从静态更改为实例是行不通的,因为我最终会得到 4 个实例,每个实例只包含一个值...

最佳答案

这会起作用。我相信它被称为奇怪的重复模板模式,但不要引用我的话

public abstract class Base<TSelf, TKey, TValue>
{
    private static readonly IDictionary<TKey, Base<TSelf, TKey, TValue>> Values = 
        new Dictionary<TKey, Base<TSelf, TKey, TValue>>();

    public TKey Key { get; private set; }
    public TValue Value { get; private set; }

    protected Base(TKey key, TValue value)
    {
        this.Key = key;
        this.Value = value;

        Values.Add(key, this);
    }
}


public sealed class One : Base<One, string, string>
{
    public static readonly One Default = new One("DEF", "Default value");
    public static readonly One Invalid = new One("", "Invalid value");

    private One(string key, string value) : base(key, value) { }
}

public sealed class Two : Base<Two, string, string>
{
    public static readonly Two EU = new Two("EU", "European Union");
    public static readonly Two USA = new Two("", "United States of America");

    private Two(string key, string value) : base(key, value) { }
}

“奇怪”的部分是 OneTwo 的定义被允许将它们自己用作它们自己的类型参数!

关于c# - 继承和共享静态字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11104185/

相关文章:

c# - 查找类是否继承接口(interface)的更有效方法?

c++ - 使用不受支持的类方法时抛出编译器错误

来自基类的 C# 泛型方法

java - 未定义的构造函数(java)

c# - CM Bootstrap 在 Root View 之前显示一个窗口

c# - 当http请求超时时重试多次使用polly c#

generics - 您能否扩展具有特定约束的通用类(例如 Array)?

基于 Scala 类型的属性提取器 - Getter only Lens?

c# - 如何获取类型中的方法

c# - 针对相同版本的 .NET 框架的随机数种子