我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
当前回答
我甚至按照@Even(通过类X和公共静态X成员)的建议实现了一些枚举,只是为了后来发现,从。net 4.5开始,有了正确的ToString()方法。
现在我将所有内容重新实现为枚举。
其他回答
基于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
我只需创建一个字典,并使用代码作为键。
编辑:为了解决关于执行反向查找(查找键)的注释,这将不是非常有效。如果有必要,我将编写一个新类来处理它。
你也可以使用扩展模型:
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());
我喜欢在类中使用属性而不是方法,因为它们看起来更像枚举。
下面是一个Logger的例子:
public class LogCategory
{
private LogCategory(string value) { Value = value; }
public string Value { get; private set; }
public static LogCategory Trace { get { return new LogCategory("Trace"); } }
public static LogCategory Debug { get { return new LogCategory("Debug"); } }
public static LogCategory Info { get { return new LogCategory("Info"); } }
public static LogCategory Warning { get { return new LogCategory("Warning"); } }
public static LogCategory Error { get { return new LogCategory("Error"); } }
public override string ToString()
{
return Value;
}
}
传入类型安全的字符串值作为参数:
public static void Write(string message, LogCategory logCategory)
{
var log = new LogEntry { Message = message };
Logger.Write(log, logCategory.Value);
}
用法:
Logger.Write("This is almost like an enum.", LogCategory.Info);
这是一种将它用作强类型参数或字符串的方法:
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");
}