假设我有一个通用抽象类,它提供了一些默认的构造函数功能,这样您就不必在继承类中重复代码:
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) { }
}
“奇怪”的部分是 One
和 Two
的定义被允许将它们自己用作它们自己的类型参数!
关于c# - 继承和共享静态字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11104185/