Это немного странно / сложно и больше просто любопытство, чем что-либо.
Я искал способ убедиться, что статические вызовы из базового класса могут безопасно использовать статическую информацию, заданную в производном классе.Затем я заметил, что C # позволяет мне вызывать статический конструктор производного класса в статическом конструкторе базового класса.
Мой вопрос: Безопасно ли вызывать статический конструктор производного класса в статическом конструкторе базового класса
Вот пример кода:
public abstract class Enumeration<TEnum, TValue>
where TEnum : Enumeration<TEnum, TValue> // << Note the CRTP-ish thing
where TValue: class
{
private static readonly Dictionary<string, Enumeration<TEnum, TValue>> Mapping = new Dictionary<string, Enumeration<TEnum, TValue>>();
public TValue Value { get; }
public string Name { get; }
// Base class calling derived static constructor. This sets up "Mapping" with derived class enumerations
static Enumeration()
{
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(TEnum).TypeHandle);
}
// Static member "Mapping" filled using this constructor when derived class statics are initialized
protected Enumeration(TValue enumValue, string name)
{
Value = enumValue;
Name = name;
Mapping.Add(name, this);
}
// Uses "Mapping", so "Mappings" needs to be filled before this is called.
protected static IEnumerable<TEnum> All => Mapping.Values.AsEnumerable().Cast<TEnum>();
public override string ToString() { return Name; }
}
public sealed class DerivedEnum : Enumeration<DerivedEnum, String>
{
// This static member will input itself into the static "Mapping" in the base class
public static readonly DerivedEnum A = new DerivedEnum("A", "A");
private DerivedEnum(string val, string name) : base(val, name) {}
}
Я провел несколько базовых тестов, и он, похоже, не сломался.Есть ли способ, которым это может сломаться?
Вот скрипка, если вам нужно ... fiddle: https://dotnetfiddle.net/mREPyL
Кроме того, мой код вдохновлен этим ответом .Я хотел посмотреть, смогу ли я получить производные классы более краткими.