字符串枚举自定义类<T>与具有属性 C# 的枚举



经过调查,我得出结论,对于我的目的来说,什么样的带属性的string Enum太慢而且不方便。

所以我的问题-我的实现是正常的还是多余的和危险的?=)

public class StringEnum<TChildType> where TChildType: StringEnum<TChildType>, new()
{            
     private readonly Type childType;
     private string _value;
     private readonly HashSet<string> members;
     public string Value
     {
        get { return _value; }
        set
        {
            if (!Contains(value))
                {
                    throw new NotImplementedException(String.Format("Value '{0}' wasnt found in Enum", value));
                }
                _value = value;
            }
        }
        public IEnumerable<string> Values
        {
            get { return members; }
        }
        public bool Contains(string value)
        {
            return members.Contains(value);
        }
        public static IEnumerable<string> GetValues()
        {
            return Service.GetGenericConstProperties<string>(typeof(TChildType));
        }
        public StringEnum()
        {
            childType = typeof(TChildType);
            members = Service.GetGenericStaticProperties<string>(childType).ToHashSet();
            if (members.Count < 2) throw new Exception("Fill Enum!");               
        }
        public static implicit operator StringEnum<TChildType>(string str)
        {
            return new TChildType { Value = str };
        }
        public static implicit operator string(StringEnum<TChildType> source)
        {
            return source != null ? source.Value : null;
        }
    }
Enum的例子:

public class PrinterType : StringEnum<PrinterType>
{
   public const string CommonPrinter = "... ...";
   .....
}

如何使用:

public class MyPrinter
{
   public StringEnum<PrinterType> PrintType = PrinterType.CommonPrinter;
}
        var list = PrinterType.GetValues().ToList();
        var e = new MyPrinter();
        var q = e.PrintType;
        if (e.PrintType == PrinterType.Ярлыков)
           ...
        if (e.PrintType.Contains("jh"))

或类似于backback字段:

        private StringEnum<PrinterType> _type;
        public string Type {... return _type... }

我将这样修改:

public class StringEnum<TChildType> where TChildType : StringEnum<TChildType>, new()
{
    private static readonly HashSet<string> members;
    private static readonly List<string> sortedmembers;
    private string _value;
    public string Value
    {
        get { return _value; }
        protected set
        {
            if (!Contains(value))
            {
                throw new ArgumentException(String.Format("Value '{0}' wasnt found in Enum", value));
            }
            _value = value;
        }
    }
    public static IEnumerable<string> Values
    {
        get { return sortedmembers; }
    }
    public static bool Contains(string value)
    {
        return members.Contains(value);
    }
    static StringEnum()
    {
        sortedmembers = Service.GetGenericConstProperties<string>(typeof(TChildType)); // .ToList() if necessary
        members = new HashSet<string>(sortedmembers);
        if (members.Count < 2) throw new Exception("Fill Enum!");
    }
    public static implicit operator StringEnum<TChildType>(string str)
    {
        return new TChildType { Value = str };
    }
    public static implicit operator string(StringEnum<TChildType> source)
    {
        return source != null ? source.Value : null;
    }
    public static StringEnum<TChildType> Parse(string value)
    {
        return (StringEnum<TChildType>)value;
    }
    public override string ToString()
    {
        return (string)this;
    }
    public override int GetHashCode()
    {
        return StringComparer.Ordinal.GetHashCode(Value);
    }
    public override bool Equals(object obj)
    {
        StringEnum<TChildType> value = obj as StringEnum<TChildType>;
        if (object.ReferenceEquals(value, null))
        {
            return false;
        }
        return StringComparer.Ordinal.Equals(Value, value.Value);
    }
}

与所有值类型一样,enum是不可变的。你改变不了。你只能重新分配它。我在这里也做同样的事情。Value.set是受保护的,只能在StringEnum<>的子类内部使用。

我已经实现了GetHashCode/Equals/ToString

我已经将所有的内部集合移动到static成员,因为它们对于相同TChildType的所有StringEnum都是通用的

最新更新