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

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

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

我还有其他选择吗?


当前回答

基于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

其他回答

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

    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;
   }

我只需创建一个字典,并使用代码作为键。

编辑:为了解决关于执行反向查找(查找键)的注释,这将不是非常有效。如果有必要,我将编写一个新类来处理它。

你也可以使用扩展模型:

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());

你可以很容易地做到。使用下面的代码。

enum GroupTypes
{
   OEM,
   CMB
};

然后,当您想获取每个枚举元素的字符串值时,只需使用下面的代码行。

String oemString = Enum.GetName(typeof(GroupTypes), GroupTypes.OEM);

我曾经成功地使用过这个方法,我也使用过一个常量类来保存字符串常量,两者都很好,但我倾向于这样做。

Glennular Extension方法的一个小调整,所以你可以在其他东西上使用扩展,而不仅仅是ENUM的;

using System;
using System.ComponentModel;
namespace Extensions {
    public static class T_Extensions {
        /// <summary>
        /// Gets the Description Attribute Value
        /// </summary>
        /// <typeparam name="T">Entity Type</typeparam>
        /// <param name="val">Variable</param>
        /// <returns>The value of the Description Attribute or an Empty String</returns>
        public static string Description<T>(this T t) {
            DescriptionAttribute[] attributes = (DescriptionAttribute[])t.GetType().GetField(t.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
            return attributes.Length > 0 ? attributes[0].Description : string.Empty;
        }
    }
}

或者使用Linq

using System;
using System.ComponentModel;
using System.Linq;

namespace Extensions {


public static class T_Extensions {
        public static string Description<T>(this T t) =>
            ((DescriptionAttribute[])t
            ?.GetType()
            ?.GetField(t?.ToString())
            ?.GetCustomAttributes(typeof(DescriptionAttribute), false))
            ?.Select(a => a?.Description)
            ?.FirstOrDefault() 
            ?? string.Empty;  
    }
}