我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
当前回答
根据其他人的意见,这是我想到的。这种方法避免了在想要获得常量值的地方键入. value。
我有一个基类的所有字符串枚举像这样:
using System;
using Newtonsoft.Json;
[JsonConverter(typeof(ConstantConverter))]
public class StringEnum: IConvertible
{
public string Value { get; set; }
protected StringEnum(string value)
{
Value = value;
}
public static implicit operator string(StringEnum c)
{
return c.Value;
}
public string ToString(IFormatProvider provider)
{
return Value;
}
public TypeCode GetTypeCode()
{
throw new NotImplementedException();
}
public bool ToBoolean(IFormatProvider provider)
{
throw new NotImplementedException();
}
//The same for all the rest of IConvertible methods
}
JsonConverter是这样的:
using System;
using Newtonsoft.Json;
class ConstantConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
serializer.Serialize(writer, null);
}
else
{
serializer.Serialize(writer, value.ToString());
}
}
}
一个实际的string enum是这样的:
public sealed class Colors : StringEnum
{
public static Colors Red { get { return new Catalog("Red"); } }
public static Colors Yellow { get { return new Catalog("Yellow"); } }
public static Colors White { get { return new Catalog("White"); } }
private Colors(string value) : base(value) { }
}
有了这个,你可以使用颜色。红色甚至序列化到json而不使用Value属性
其他回答
我喜欢在类中使用属性而不是方法,因为它们看起来更像枚举。
下面是一个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);
我基本上是在寻找@ArthurC的反思答案
稍微扩展一下他的回答,你可以通过一个泛型函数来让它更好:
// If you want for a specific Enum
private static string EnumStringValue(GroupTypes e)
{
return EnumStringValue<GroupTypes>(e);
}
// Generic
private static string EnumStringValue<T>(T enumInstance)
{
return Enum.GetName(typeof(T), enumInstance);
}
然后你就可以把你有的东西都包起来了
EnumStringValue(GroupTypes.TheGroup) // if you incorporate the top part
or
EnumStringValue<GroupTypes>(GroupTypes.TheGroup) // if you just use the generic
根据其他人的意见,这是我想到的。这种方法避免了在想要获得常量值的地方键入. value。
我有一个基类的所有字符串枚举像这样:
using System;
using Newtonsoft.Json;
[JsonConverter(typeof(ConstantConverter))]
public class StringEnum: IConvertible
{
public string Value { get; set; }
protected StringEnum(string value)
{
Value = value;
}
public static implicit operator string(StringEnum c)
{
return c.Value;
}
public string ToString(IFormatProvider provider)
{
return Value;
}
public TypeCode GetTypeCode()
{
throw new NotImplementedException();
}
public bool ToBoolean(IFormatProvider provider)
{
throw new NotImplementedException();
}
//The same for all the rest of IConvertible methods
}
JsonConverter是这样的:
using System;
using Newtonsoft.Json;
class ConstantConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
serializer.Serialize(writer, null);
}
else
{
serializer.Serialize(writer, value.ToString());
}
}
}
一个实际的string enum是这样的:
public sealed class Colors : StringEnum
{
public static Colors Red { get { return new Catalog("Red"); } }
public static Colors Yellow { get { return new Catalog("Yellow"); } }
public static Colors White { get { return new Catalog("White"); } }
private Colors(string value) : base(value) { }
}
有了这个,你可以使用颜色。红色甚至序列化到json而不使用Value属性
使用带有常量的静态类如何?
static class GroupTypes
{
public const string TheGroup = "OEM";
public const string TheOtherGroup = "CMB";
}
void DoSomething(string groupType)
{
if(groupType == GroupTypes.TheGroup)
{
// Be nice
}
else if (groupType == GroupTypes.TheOtherGroup)
{
// Continue to be nice
}
else
{
// unexpected, throw exception?
}
}
你也可以使用扩展模型:
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());