2013-06-23 132 views
2

enums喜欢在我的数据库如下:如何用空格表示枚举值?

“随机型”,“随机类型1”,“NewRandom”

通常情况下,我将代表一个枚举值,如:

enum myTypes 
{ 
    Random Type = 0,... 
} 

,但是这是不可能的,所以我尝试使用类

static class myTypes 
{ 
    public const string RandomType = "Random Type"; 
    public const string NewRandom = "NewRandom"; 
} 

这样,我可以使用类如Enum,但我想知道这是否是最好的实现可能?或者在创建Enums以留出空间吗?

谢谢。

编辑: 请,我也想知道我目前的实施是否有任何问题。我有一种感觉,我现在的实施比这里提出的大多数解决方案都要好。

由于

+0

寻找T4模板.... –

+0

为什么不在调用Enum中的“随机类型”RandomType? – Magnus

+0

@Magnus:因为我正在检索'Enum'名字。 – rtuner

回答

2

枚举得多类似编号(整数特异性),而不是串左右。坚持编号的枚举可以让你轻松地投射,标记合成(例如,AND,OR等)。

我不会使用字符串常量来代替枚举,除非这会为您带来更多好处而不是惩罚。

如果您的目标是向用户描述枚举选项,我建议考虑使用Description属性来丰富每个项目。这是一个元数据,而不是真实的数据,但使用反射也很容易阅读。

干杯

+0

我正在使用枚举名称。 – rtuner

+0

从字符串开始,您应该解析它们以获取Enum项目。您不能使用Enum对象的“Parse”方法,但可以搜索匹配的描述(for-loop或hash-map)。如果你有很少的选择,那么简单的转换就足够了,这是不值得的。 –

0

你应该使用字符串作为数据库类型的指标。改用整数。如果你喜欢,你可以在你的数据库中有一个“类型表”,在那里你可以存储类型名,而不是通过使用它们的表重复它们。

如果您这样做,那么您可以将数据库中的整数转换为枚举,如上所示。

2

我所做的是定义可以附加到枚举值的自定义属性[DisplayName(string)]。你可以定义你希望被命名为空格/特殊字符值与显示名称的枚举:

public enum Test 
{ 
    None = 0, 

    [DisplayName("My Value")] 
    MyValue = 1, 

    [DisplayName("Spęćiał")] 
    Special = 2 
} 

你除了获得枚举值的名字实施也应该检查是否DisplayName属性设置,如果是这样,它应该改为显示名称。

+0

向我解释这与'[DescriptionAttribute]'的优点? –

+0

@newStackExchangeInstance您可以控制实现,以便可以根据需要扩展具有更多功能的属性(例如本地化支持)。 – ghord

+0

我知道你可以做到这一点,但对于这种特殊情况'DescriptionAttribute'更好。 –

1

我会去的显示名称属性:

[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值如果您省略某些枚举成员的属性。

3

不,你不能那样做。枚举只是类型安全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(); 
0

您可以使用Typesafe Enum模式来实现您的目标。

想法是围绕一个类包装你的枚举。我想这是你想要的 -

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 }; 
    } 
}