我的数据库中有enums
,如下所示:
"随机类型"、"随机类型1"、"新随机"
通常,我会在枚举中表示值,如:
enum myTypes
{
Random Type = 0,...
}
但这是不可能的,所以我尝试使用类
static class myTypes
{
public const string RandomType = "Random Type";
public const string NewRandom = "NewRandom";
}
这样,我可以像使用Enum
一样使用该类,但我想知道这是否是最好的实现?或者,创建Enums
是为了留出空间吗?
谢谢。
编辑:我也想知道我目前的执行是否有什么问题。我有一种感觉,我目前的实现比这里大多数建议的解决方案都要好。
感谢
不,你不能那样做。枚举只是类型安全的int
s。
有一个可用的解决方案,我非常喜欢。使用DescriptionAttribute。
你会这样使用它:
static enum myTypes
{
[Description("Random Type")]
RandomType,
[Descripton("New Random")]
NewRandom
}
然后你还需要这个扩展方法:
public static string GetDescription<T>(this T en) where T : struct, IConvertible
{
Type type = typeof(T);
if (!type.IsEnum)
{
throw new ArgumentException("The type is not an enum");
}
MemberInfo[] memInfo = type.GetMember(en.ToString());
if (memInfo != null && memInfo.Length > 0)
{
object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
{
return ((DescriptionAttribute)attrs[0]).Description;
}
}
return en.ToString();
}
然后,你可以这样做:
myTypes.RandomType.GetDescription();
枚举与数字(特别是整数)非常相似,而不是字符串之类的。坚持使用带编号的枚举可以使您轻松进行类型转换、标记组合(例如AND、or等)。
我不会用字符串常量代替枚举,除非这会给您带来比惩罚更多的好处。
如果您的目标是向用户描述Enum选项,我建议考虑使用Description属性来丰富每个项。它是一个元数据,而不是一个真实的数据,但使用反射也很容易读取。
干杯
我所做的是定义可以附加到枚举值的自定义属性[DisplayName(string)]
。您可以在您希望使用空格/特殊字符命名的值上定义显示名称的枚举:
public enum Test
{
None = 0,
[DisplayName("My Value")]
MyValue = 1,
[DisplayName("Spęćiał")]
Special = 2
}
除了获取枚举值名称之外,您的实现还应该检查是否设置了DisplayName
属性,如果设置了,则应该使用显示名称。
我会使用显示名称属性:
[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : DisplayNameAttribute
{
public EnumDisplayNameAttribute()
: base(string.Empty)
{
}
public EnumDisplayNameAttribute(string displayName)
: base(displayName)
{
}
}
public static class EnumExtensions
{
public static string ToDisplayName(this Enum enumValue)
{
var builder = new StringBuilder();
var fields = GetEnumFields(enumValue);
if (fields[0] != null)
for (int i = 0; i < fields.Length; i++)
{
var value = fields[i]
.GetCustomAttributes(typeof(EnumDisplayNameAttribute), false)
.OfType<EnumDisplayNameAttribute>()
.FirstOrDefault();
builder.Append(value != null
? value.DisplayName
: enumValue.ToString());
if (i != fields.Length - 1)
builder.Append(", ");
}
return builder.ToString();
}
private static FieldInfo[] GetEnumFields(Enum enumValue)
{
var type = enumValue.GetType();
return enumValue
.ToString()
.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(type.GetField)
.ToArray();
}
}
类型用法:
public enum MyType
{
[DisplayName("Random Type")]
RandomType,
[DisplayName("New Random")]
NewRandom
}
将是:
var enumVariable = MyType.RandomType;
var stringRepresentation = enumVariable.ToDisplayName();
注意,使用该方法,如果省略某些枚举成员的属性,则会获得ToString值。
您可能不应该在数据库中使用字符串作为类型指示符。请改用整数。如果您愿意,您可以在数据库中有一个"类型表",在那里您可以存储类型名称,而不是在使用它们的表中重复它们。
如果您这样做,那么您可以将数据库中的整数转换为枚举,如上所述。
您可以使用Typesafe枚举模式来实现您的目标。
想法是把你的枚举包在一个类上。我想这就是你想要的-
public class MyTypes
{
#region Enum Values
public static MyTypes RandomType = new MyTypes(0, "Random Type");
public static MyTypes NewRandom = new MyTypes(1, "New Random");
#endregion
#region Private members
private int id;
private string value;
private MyTypes(int id, string value)
{
this.id = id;
this.value = value;
}
#endregion
#region Overriden members
public override string ToString()
{
return value;
}
#endregion
public static List<MyTypes> GetValues()
{
return new List<MyTypes>() { MyTypes.RandomType, MyTypes.NewRandom };
}
}