我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
当前回答
public class DataType
{
private readonly string value;
private static readonly Dictionary<string, DataType> predefinedValues;
public static readonly DataType Json = new DataType("json");
public static readonly DataType Xml = new DataType("xml");
public static readonly DataType Text = new DataType("text");
public static readonly DataType Html = new DataType("html");
public static readonly DataType Binary = new DataType("binary");
static DataType()
{
predefinedValues = new Dictionary<string, DataType>();
predefinedValues.Add(Json.Value, Json);
predefinedValues.Add(Xml.Value, Xml);
predefinedValues.Add(Text.Value, Text);
predefinedValues.Add(Html.Value, Html);
predefinedValues.Add(Binary.Value, Binary);
}
private DataType(string value)
{
this.value = value;
}
public static DataType Parse(string value)
{
var exception = new FormatException($"Invalid value for type {nameof(DataType)}");
if (string.IsNullOrEmpty(value))
throw exception;
string key = value.ToLower();
if (!predefinedValues.ContainsKey(key))
throw exception;
return predefinedValues[key];
}
public string Value
{
get { return 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());
这是一种将它用作强类型参数或字符串的方法:
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");
}
摘自@EvenMien,并添加了一些评论。(也适用于我自己的用例)
public struct AgentAction
{
private AgentAction(string value) { Value = value; }
public string Value { get; private set; }
public override string ToString() { return this.Value; }
public static AgentAction Login = new AgentAction("Login");
public static AgentAction Logout = new AgentAction("Logout");
public static implicit operator string(AgentAction action) { return action.ToString(); }
}
如果我理解正确,你需要一个从字符串到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");
如果您愿意,可以使用枚举类型的泛型使其更加花哨。
下面是我对这个问题的看法,使用c# 9.0语法来保持整洁。我为枚举定义了一个基类:
public class StringEnum
{
protected StringEnum(string value) { Value = value; }
public string Value { get; }
public override string ToString() => Value;
}
创建新的枚举样式类型是简单而紧凑的:
public class GroupTypes : StringEnum
{
private GroupTypes(string value) : base(value) {}
public static readonly GroupTypes TheGroup = new("OEM");
public static readonly GroupTypes TheOtherGroup = new("CMB");
}
像这样使用它:
void Example(GroupTypes groupType)
{
Console.WriteLine(groupType); // Will print "OEM" or "CMB"
if (groupType == GroupTypes.TheGroup) { ... }
}
你也可以给StringEnum添加更多的功能,这样你的所有子类都可以使用(例如,实现IComparable和重写Equals和GetHashCode)