我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
当前回答
你可以很容易地做到。使用下面的代码。
enum GroupTypes
{
OEM,
CMB
};
然后,当您想获取每个枚举元素的字符串值时,只需使用下面的代码行。
String oemString = Enum.GetName(typeof(GroupTypes), GroupTypes.OEM);
我曾经成功地使用过这个方法,我也使用过一个常量类来保存字符串常量,两者都很好,但我倾向于这样做。
其他回答
基于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
你可以很容易地做到。使用下面的代码。
enum GroupTypes
{
OEM,
CMB
};
然后,当您想获取每个枚举元素的字符串值时,只需使用下面的代码行。
String oemString = Enum.GetName(typeof(GroupTypes), GroupTypes.OEM);
我曾经成功地使用过这个方法,我也使用过一个常量类来保存字符串常量,两者都很好,但我倾向于这样做。
如果你喜欢自己编写扩展,上面有几个很好的答案
我使用CodeHelper.Core.Extensions
enum GroupTypes
{
[StringValue("OEM")] TheGroup,
[StringValue("CMB")] TheOtherGroup = "CMB"
}
GroupTypes.TheOtherGroup.ToStringValue()
如果你没有将StringValue属性添加到值中,扩展将返回正常名称(.ToTring()) 并且超级容易添加空格和其他通常不允许的字符,如空格或以数字开头
你也可以使用扩展模型:
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本身,以便您能够确定是否应用了该属性。