.NET Fiddle

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Linq;

public abstract class Enumeration<TEnum, TValue>
        where TEnum : Enumeration<TEnum, TValue>
        where TValue: class, IComparable
    {
        private static readonly Dictionary<string, Enumeration<TEnum, TValue>> Mapping = new Dictionary<string, Enumeration<TEnum, TValue>>();

        public TValue Value { get; private set; }
        public string Name { get; private set; }
		
		static Enumeration()
		{
			Console.WriteLine("Static base Constructor called");
			System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(TEnum).TypeHandle);
		}

        protected Enumeration(TValue enumValue, string name)
        {
            Value = enumValue;
            Name = name;
            Mapping.Add(name, this);
        }

        public static TEnum Parse(string name)
        {
			Enumeration<TEnum, TValue> result;
            if (Mapping.TryGetValue(name, out result))
            {
                return (TEnum)result;
            }

            throw new InvalidCastException();
        }

        public static IEnumerable<TEnum> All { get { return Mapping.Values.AsEnumerable().Cast<TEnum>(); } }

        public override string ToString() { return Name; }
    }
	
public sealed class DerivedEnum : Enumeration<DerivedEnum, String>
{
  static DerivedEnum()
  {
    Console.WriteLine("Static Derived constructor Called");
  }

  public static readonly DerivedEnum A = new DerivedEnum("blah", "blah");
  
  private DerivedEnum(string val, string name) : base(val, name) {}
  public static explicit operator DerivedEnum(string str) { return Parse(str); }
}

public class Program
{
	public static void Main()
	{
		//var a = DerivedEnum.A;
		Console.WriteLine("Count: " + DerivedEnum.All.Count());
		Console.WriteLine("Parse Blah:" + DerivedEnum.Parse("blah"));
	}
}
;