字符串枚举自定义类<t> vs Enum,带有属性C#

时间:2015-05-19 08:34:31

标签: c# string generics enums

经过调查我得出结论,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;
        }
    }

枚举示例:

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"))

甚至喜欢支持Field:

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

1 个答案:

答案 0 :(得分:1)

我会这样改变:

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成员,因为它们对同一StringEnum

的所有TChildType都很常见