C#使用枚举类(而不是枚举类型)

83 阅读1分钟

使用枚举类(而不是枚举类型)

1、定义枚举基类

public abstract class Enumeration : IComparable
    {
        public string Name { get; private set; }

        public int Id { get; private set; }

        protected Enumeration(int id, string name) => (Id, Name) = (id, name);

        public override string ToString() => Name;

        public static IEnumerable<T> GetAll<T>() where T : Enumeration =>
            typeof(T).GetFields(BindingFlags.Public |
                                BindingFlags.Static |
                                BindingFlags.DeclaredOnly)
                        .Select(f => f.GetValue(null))
                        .Cast<T>();

        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)
        {
            var absoluteDifference = Math.Abs(firstValue.Id - secondValue.Id);
            return absoluteDifference;
        }

        public static T FromValue<T>(int value) where T : Enumeration
        {
            var matchingItem = Parse<T, int>(value, "value", item => item.Id == value);
            return matchingItem;
        }

        public static T FromDisplayName<T>(string displayName) where T : Enumeration
        {
            var matchingItem = Parse<T, string>(displayName, "display name", item => item.Name == displayName);
            return matchingItem;
        }

        private static T Parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration
        {
            var matchingItem = GetAll<T>().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);
    }

2、实现枚举基类

public class SlabTemperatureStatus : Enumeration
    {
        public static SlabTemperatureStatus Warm = new SlabTemperatureStatus(1, nameof(Warm).ToLowerInvariant());
        public static SlabTemperatureStatus Hot = new SlabTemperatureStatus(2, nameof(Hot).ToLowerInvariant());
        public static SlabTemperatureStatus Cold = new SlabTemperatureStatus(3, nameof(Cold).ToLowerInvariant());

        public SlabTemperatureStatus(int id, string name) : base(id, name)
        {
        }
    }

3、使用

public string SlabStatus { protected set; get; }

public RollPlanItem SetSlabStatus(SlabTemperatureStatus status)
{
    Check.NotNull(status, nameof(status));
    SlabStatus = status.Name;
    return this;
}

public RollPlanItem SetSlabStatus(string slabStatus)
{
    Check.NotNullOrEmpty(slabStatus, nameof(slabStatus));

    var slabStatusEnum = Enumeration.FromDisplayName<SlabTemperatureStatus>(slabStatus);
    SlabStatus = slabStatusEnum.Name;
    return this;
}