using System.Reflection; namespace ZeroFramework.DeviceCenter.Domain.Entities { public abstract class Enumeration : IComparable { public string Name { get; private set; } public int Id { get; private set; } protected Enumeration(int id, string name) { Id = id; Name = name; } public override string ToString() => Name; public static IEnumerable GetAll() where T : Enumeration { var fields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly); return fields.Select(f => f.GetValue(null)).Cast(); } public override bool Equals(object? obj) { if (obj is not Enumeration otherValue) { return false; } var typeMatches = GetType().Equals(obj?.GetType()); var valueMatches = Id.Equals(otherValue.Id); return typeMatches && valueMatches; } public override int GetHashCode() => Id.GetHashCode(); public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue) => Math.Abs(firstValue.Id - secondValue.Id); public static T FromValue(int value) where T : Enumeration { var matchingItem = Parse(value, "value", item => item.Id == value); return matchingItem; } public static T FromDisplayName(string displayName) where T : Enumeration { 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 { var matchingItem = GetAll().FirstOrDefault(predicate); if (matchingItem == null) { throw new InvalidOperationException($"'{value}' is not a valid {description} in {typeof(T)}"); } return matchingItem; } public int CompareTo(object? other) => Id.CompareTo(((Enumeration?)other)?.Id); } }