【问题标题】:How to represent enum values with space?如何用空格表示枚举值?
【发布时间】:2013-06-23 09:52:04
【问题描述】:

我的数据库中有enums,如下所示:

“随机类型”、“随机类型1”、“新随机”

通常,我会在枚举中表示值,例如:

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

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

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

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

谢谢。

编辑: 拜托,我也很想知道我当前的实现是否有任何问题。我感觉我目前的实现比这里建议的大多数解决方案都要好。

谢谢

【问题讨论】:

  • 搜索 T4 模板....
  • 为什么不在枚举中调用“随机类型”RandomType
  • @Magnus:因为我正在检索 Enum 名称。
  • 使用这些检索键而不是映射。
  • 你能告诉我怎么做吗??

标签: c# mysql performance enums


【解决方案1】:

不,你不能那样做。枚举只是类型安全的ints。

有一个可用的解决方案,我非常喜欢它。使用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();

【讨论】:

    【解决方案2】:

    枚举与数字(特别是整数)非常相似,而不是字符串左右。坚持编号的枚举可以让您轻松地进行转换、标志组合(例如 AND、OR 等)。

    我不会使用字符串常量来代替枚举,除非这会给你带来比惩罚更多的好处。

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

    干杯

    【讨论】:

    • 我正在使用枚举名称。
    • 从字符串开始,你应该解析它们以获得一个枚举项。您不能使用 Enum 对象的“Parse”方法,但您可以搜索匹配的描述(for-loop 或 hash-map)。如果您的选择很少,那么这是不值得的,一个简单的开关就足够了。
    【解决方案3】:

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

    public enum Test
    {
        None = 0,
    
        [DisplayName("My Value")]
        MyValue = 1,
    
        [DisplayName("Spęćiał")]
        Special = 2
    }
    

    除了获取枚举值名称外,您的实现还应检查是否设置了DisplayName 属性,如果设置了,则应使用显示名称。

    【讨论】:

    • 向我解释这对[DescriptionAttribute]的优势?
    • @newStackExchangeInstance 您可以控制实现,因此如果您愿意,可以使用更多功能扩展属性(例如本地化支持)。
    • 我知道你可以这样做,但对于这种特殊情况,DescriptionAttribute 更好。
    【解决方案4】:

    我会选择显示名称属性:

    [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 值。

    【讨论】:

      【解决方案5】:

      您可能应该在数据库中使用字符串作为类型指示符。请改用整数。如果您愿意,您可以在数据库中创建一个“类型表”,您可以在其中存储类型名称,而不是在使用它们的表中重复它们。

      如果你这样做,那么你可以按照上面的建议将整数从数据库转换为枚举。

      【讨论】:

        【解决方案6】:

        您可以使用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 };
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-24
          • 1970-01-01
          • 1970-01-01
          • 2011-04-15
          相关资源
          最近更新 更多