Явный вызов статического конструктора в базовом статическом конструкторе - PullRequest
2 голосов
/ 22 марта 2019

Это немного странно / сложно и больше просто любопытство, чем что-либо.

Я искал способ убедиться, что статические вызовы из базового класса могут безопасно использовать статическую информацию, заданную в производном классе.Затем я заметил, что 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

Кроме того, мой код вдохновлен этим ответом .Я хотел посмотреть, смогу ли я получить производные классы более краткими.

...