Skip to content

Instantly share code, notes, and snippets.

@cgbeutler
Created March 22, 2019 17:09
Show Gist options
  • Save cgbeutler/bd6553c409a280620fc9f2256e6c469d to your computer and use it in GitHub Desktop.
Save cgbeutler/bd6553c409a280620fc9f2256e6c469d to your computer and use it in GitHub Desktop.
C# generic enumeration
public sealed class ExampleEnumeration : Enumeration<ExampleEnumeration, string>
{
public static readonly ExampleEnumeration Value = new ExampleEnumeration(nameof(Value));
public static readonly ExampleEnumeration Value2 = new ExampleEnumeration(nameof(Value2), "Value 2");
private ExampleEnumeration(string value, string name = null) : base(value, name ?? value) {}
}
/// <summary>
/// Enumeration representation that can take all types
/// </summary>
/// <typeparam name="TEnum">The derived type that inherits from this base class (CRTP)</typeparam>
/// <typeparam name="TValue">The type of the value of the enum</typeparam>
public abstract class Enumeration<TEnum, TValue> : IComparable
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; }
public string Name { get; }
static Enumeration()
{
// Ensure that we set up the derived class's enum members to fill the "Mapping" dictionary
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)
{
if (Mapping.TryGetValue(name, out var result))
{
return (TEnum)result;
}
throw new InvalidCastException();
}
public static IEnumerable<TEnum> All => Mapping.Values.AsEnumerable().Cast<TEnum>();
public override string ToString() { return Name; }
public override bool Equals(object obj)
{
if (!(obj is TEnum otherValue))
return false;
return Value.Equals(otherValue.Value);
}
public int CompareTo(object other) => Value.CompareTo(((TEnum)other).Value);
public override int GetHashCode()
{
return 2108858624 + Value.GetHashCode();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment