我知道下面是不可能的,因为枚举的类型必须是int

enum GroupTypes
{
    TheGroup = "OEM",
    TheOtherGroup = "CMB"
}

从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。

我还有其他选择吗?


当前回答

我使用了在之前的回答中提到的结构,但去掉了任何复杂性。对我来说,这就像创建一个字符串枚举。它的使用方式与枚举的使用方式相同。

    struct ViewTypes
    {
        public const string View1 = "Whatever string you like";
        public const string View2 = "another string";
    }

使用示例:

   switch( some_string_variable )
   {
      case ViewTypes.View1: /* do something */ break;
      case ViewTypes.View2: /* do something else */ break;
   }

其他回答

尝试向静态类中添加常量。你最终不会得到一个Type,但你会得到可读的、有组织的常量:

public static class GroupTypes {

    public const string TheGroup = "OEM";
    public const string TheOtherGroup = "CMB";

}

如果我理解正确,你需要一个从字符串到enum的转换:

enum GroupTypes {
    Unknown = 0,
    OEM = 1,
    CMB = 2
}
static GroupTypes StrToEnum(string str){
    GroupTypes g = GroupTypes.Unknown;
    try {
        object o = Enum.Parse(typeof(GroupTypes), str, true);
        g = (GroupTypes)(o ?? 0);
    } catch {
    }
    return g;
}
// then use it like this
GroupTypes g1 = StrToEnum("OEM");
GroupTypes g2 = StrToEnum("bad value");

如果您愿意,可以使用枚举类型的泛型使其更加花哨。

你也可以使用扩展模型:

public enum MyEnum
{
    [Description("String 1")]
    V1= 1,
    [Description("String 2")]
    V2= 2
} 

你的扩展类

public static class MyEnumExtensions
{
    public static string ToDescriptionString(this MyEnum val)
    {
        DescriptionAttribute[] attributes = (DescriptionAttribute[])val
           .GetType()
           .GetField(val.ToString())
           .GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length > 0 ? attributes[0].Description : string.Empty;
    }
} 

用法:

MyEnum myLocal = MyEnum.V1;
print(myLocal.ToDescriptionString());

可以向枚举中的项添加属性,然后使用反射从属性中获取值。

你必须使用"field"说明符来应用属性,如下所示:

enum GroupTypes
{
    [field:Description("OEM")]
    TheGroup,

    [field:Description("CMB")]
    TheOtherGroup
}

然后你将反射枚举类型的静态字段(在本例中是GroupTypes),并使用反射获取你正在寻找的值的DescriptionAttribute:

public static DescriptionAttribute GetEnumDescriptionAttribute<T>(
    this T value) where T : struct
{
    // The type of the enum, it will be reused.
    Type type = typeof(T);

    // If T is not an enum, get out.
    if (!type.IsEnum) 
        throw new InvalidOperationException(
            "The type parameter T must be an enum type.");

    // If the value isn't defined throw an exception.
    if (!Enum.IsDefined(type, value))
        throw new InvalidEnumArgumentException(
            "value", Convert.ToInt32(value), type);

    // Get the static field for the value.
    FieldInfo fi = type.GetField(value.ToString(), 
        BindingFlags.Static | BindingFlags.Public);

    // Get the description attribute, if there is one.
    return fi.GetCustomAttributes(typeof(DescriptionAttribute), true).
        Cast<DescriptionAttribute>().SingleOrDefault();
}

我选择在上面返回DescriptionAttribute本身,以便您能够确定是否应用了该属性。

我的第一个问题-你有访问数据库本身的权限吗?这应该在数据库中规范化,否则,任何解决方案都将容易出错。根据我的经验,充满“OEM”和“CMB”的数据字段往往会随着时间的推移混合“OEM”和其他“垃圾数据”....如果可以规范化它,就可以使用包含元素的表中的键作为Enum,这样就完成了,结构更加简洁。

如果这是不可用的,我将使你的Enum,并使一个类来解析你的字符串为你的Enum。这至少会让您在处理非标准条目时具有一定的灵活性,在捕获或处理错误时也比使用enumeration . parse /Reflection/etc等方法灵活得多。字典可以工作,但如果你遇到大小写问题,可能会崩溃。

我建议你写一个类,这样你就可以:

// I renamed this to GroupType, since it sounds like each element has a single type...
GroupType theType = GroupTypeParser.GetGroupType(theDBString);

这样可以保留大部分的可读性,而不必更改DB。