This one's a little weird/complex and more just curiosity than anything.
I was looking for a way to make sure static calls from a base class could safely use static information set up in a derived class. I then noticed that C# allows me to call the derived class static constructor in the base class static constructor.
My question: Is is safe to call the derived class static constructor in the base class static constructor
Here is some sample code:
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) {}
}
I have done several basic tests and it doesn't seem to break. Is there a way this could break?
Here is a fiddle if you need to... fiddle: https://dotnetfiddle.net/mREPyL
Also, my code is inspired by this answer. I wanted to see if I could get the derived classes more succinct.