using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; namespace Pole.Domain { public abstract class Enumeration : IComparable { public string Name { get; private set; } public int Id { get; private set; } protected Enumeration() { } protected Enumeration(int id, string name) { Id = id; Name = name; } public override string ToString() { return Name; } public static IEnumerable GetAll() where T : Enumeration, new() { var type = typeof(T); var fields = type.GetTypeInfo().GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach (var info in fields) { var instance = new T(); if (info.GetValue(instance) is T locatedValue) { yield return locatedValue; } } } public override bool Equals(object obj) { var otherValue = obj as Enumeration; if (otherValue == null) { return false; } var typeMatches = GetType().Equals(obj.GetType()); var valueMatches = Id.Equals(otherValue.Id); return typeMatches && valueMatches; } public override int GetHashCode() { return Id.GetHashCode(); } public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue) { var absoluteDifference = Math.Abs(firstValue.Id - secondValue.Id); return absoluteDifference; } public static T FromValue(int value) where T : Enumeration, new() { var matchingItem = Parse(value, "value", item => item.Id == value); return matchingItem; } public static T FromDisplayName(string displayName) where T : Enumeration, new() { var matchingItem = Parse(displayName, "display name", item => item.Name == displayName); return matchingItem; } private static T Parse(K value, string description, Func predicate) where T : Enumeration, new() { var matchingItem = GetAll().FirstOrDefault(predicate); if (matchingItem == null) { var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(T)); throw new InvalidOperationException(message); } return matchingItem; } public int CompareTo(object other) { return Id.CompareTo(((Enumeration)other).Id); } } }