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

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

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

我还有其他选择吗?


当前回答

您是否考虑过使用字典查找表?

enum GroupTypes
{
    TheGroup,
    TheOtherGroup
}

Dictionary<string, GroupTypes> GroupTypeLookup = new Dictionary<string, GroupTypes>();
// initialize lookup table:
GroupTypeLookup.Add("OEM", TheGroup);
GroupTypeLookup.Add("CMB", TheOtherGroup);

然后,您可以使用GroupTypeLookup.TryGetValue()在读取字符串时查找它。

其他回答

使用类。

编辑:更好的例子

class StarshipType
{
    private string _Name;
    private static List<StarshipType> _StarshipTypes = new List<StarshipType>();

    public static readonly StarshipType Ultralight = new StarshipType("Ultralight");
    public static readonly StarshipType Light = new StarshipType("Light");
    public static readonly StarshipType Mediumweight = new StarshipType("Mediumweight");
    public static readonly StarshipType Heavy = new StarshipType("Heavy");
    public static readonly StarshipType Superheavy = new StarshipType("Superheavy");

    public string Name
    {
        get { return _Name; }
        private set { _Name = value; }
    }

    public static IList<StarshipType> StarshipTypes
    {
        get { return _StarshipTypes; }
    }

    private StarshipType(string name, int systemRatio)
    {
        Name = name;
        _StarshipTypes.Add(this);
    }

    public static StarshipType Parse(string toParse)
    {
        foreach (StarshipType s in StarshipTypes)
        {
            if (toParse == s.Name)
                return s;
        }
        throw new FormatException("Could not parse string.");
    }
}

这是一种将它用作强类型参数或字符串的方法:

public class ClassLikeEnum
{
    public string Value
    {
        get;
        private set;
    }

    ClassLikeEnum(string value) 
    {
        Value = value;
    }

    public static implicit operator string(ClassLikeEnum c)
    {
        return c.Value;
    }

    public static readonly ClassLikeEnum C1 = new ClassLikeEnum("RandomString1");
    public static readonly ClassLikeEnum C2 = new ClassLikeEnum("RandomString2");
}

另一种处理这个问题的方法是,有一个枚举和一个字符串数组,将枚举值映射到字符串列表:

public enum GroupTypes
{
    TheGroup  = 0,
    TheOtherGroup 
}

string[] GroupTypesStr = {
    "OEM",
    "CMB"
};

你可以这样使用它:

Log.Write(GroupTypesStr[(int)GroupTypes.TheOtherGroup]);

它将提示CMB

优点:

简单干净的代码。 高性能(特别是与那些方法相比 使用类)

缺点:

易于混乱的列表时,编辑它,但这将是一个好的 短名单。

我会把它变成一个类,完全避免使用枚举。然后使用类型处理程序,你可以在从db中获取对象时创建对象。

即:

public class Group
{
    public string Value{ get; set; }
    public Group( string value ){ Value = value; } 
    public static Group TheGroup() { return new Group("OEM"); }
    public static Group OtherGroup() { return new Group("CMB"); }

}

基于https://stackoverflow.com/a/1343517/1818723,我提出了一个枚举与TryParse方法

public class FancyStringEnum
{
    private FancyStringEnum(string value) { Value = value; }

    public string Value { get; private set; }

    private static List<FancyStringEnum> choices = new List<FancyStringEnum>
    {
        new FancyStringEnum("Small") ,
        new FancyStringEnum("Big Thing") ,
        new FancyStringEnum("Value with Spaces")
    };

    public static FancyStringEnum Small { get { return choices[0]; } }
    public static FancyStringEnum BigThing { get { return choices[1]; } }
    public static FancyStringEnum ValueWithSpaces { get { return choices[2]; } }

    public override string ToString()
    {
        return Value;
    }

    public static bool TryParse(string value, bool ignoreCase, out FancyStringEnum result)
    {
        var sc = StringComparison.InvariantCulture;
        if (ignoreCase)
            sc = StringComparison.InvariantCultureIgnoreCase;

        foreach (var choice in choices)
        {

            if (choice.Value.Equals(value, sc))
            {
                result = choice;
                return true;
            }
        }

        result = new FancyStringEnum(null);
        return false;
    }

    public static FancyStringEnum Parse(string value, bool ignoreCase)
    {
        var sc = StringComparison.InvariantCulture;
        if (ignoreCase)
            sc = StringComparison.InvariantCultureIgnoreCase;

        foreach (var choice in choices)
        {

            if (choice.Value.Equals(value, sc))
            {
                return choice;
            }
        }

        return new FancyStringEnum(null);
    }
}

传入类型安全的字符串值作为参数:

public static void Do(string message, FancyStringEnum value)
{
    if (value == FancyStringEnum.Small)
    {
        //do something
    } else if (value == FancyStringEnum.BigThing)
    {
        //do something else
    }
}

TryParse和Parse在行动:

string something = "something"; //substiture with "small" to see it parsed 
if (FancyStringEnum.TryParse(something, true, out var se))
    Console.WriteLine(se.Value);
else
    Console.WriteLine($"unable to parse {something}");

//or    

var v2 = FancyStringEnum.Parse(something, true);
if (v2.Value == null)
    Console.WriteLine($"unable to parse {something}");
else
    Console.WriteLine(v2.Value); //do something with parsed enum

    

是否可以提取基类,用更少的代码创建StringEnums