【问题标题】:string values enum in c# [duplicate]c#中的字符串值枚举[重复]
【发布时间】:2011-02-28 02:53:53
【问题描述】:

有什么方法可以像下面这样在 c# 中定义枚举?

public enum MyEnum : string
{
    EnGb = "en-gb",
    FaIr = "fa-ir",
    ...
}

好的,根据 erick 方法和链接,我正在使用它来检查提供的描述中的有效值:

public static bool IsValidDescription(string description)
{
    var enumType = typeof(Culture);
    foreach (Enum val in Enum.GetValues(enumType))
    {
        FieldInfo fi = enumType.GetField(val.ToString());
        AmbientValueAttribute[] attributes = (AmbientValueAttribute[])fi.GetCustomAttributes(typeof(AmbientValueAttribute), false);
        AmbientValueAttribute attr = attributes[0];
        if (attr.Value.ToString() == description)
            return true;
    }
    return false;
}

有什么改善吗?

【问题讨论】:

  • 正如您从答案中看到的那样......除了基础知识之外,c# 中的枚举支持有点缺乏......尤其是您来自 C 或 C++ 世界。不要花太多时间试图让他们做他们真的不想做的事情。我有,所以你也没有:)

标签: c# .net enums


【解决方案1】:

另一种效率不高但提供枚举功能的替代方法是使用属性,如下所示:

public enum MyEnum
{
  [Description("en-gb")]
  EnGb,
  [Description("fa-ir")]
  FaIr,
  ...
}

类似于扩展方法,这是我使用的:

public static string GetDescription<T>(this T enumerationValue) where T : struct
{
  var type = enumerationValue.GetType();
  if (!type.IsEnum) throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
  var str = enumerationValue.ToString();
  var memberInfo = type.GetMember(str);
  if (memberInfo != null && memberInfo.Length > 0)
  {
    var attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
    if (attrs != null && attrs.Length > 0)
      return ((DescriptionAttribute) attrs[0]).Description;
  }
  return str;
}

那么你可以这样称呼它:

MyEnum.EnGb.GetDescription()

如果它有描述属性,你会得到它,如果没有,你会得到.ToString() 版本,例如"EnGb"。我有这样的原因是直接在 Linq-to-SQL 对象上使用枚举类型,但能够在 UI 中显示漂亮的描述。我不确定它是否适合您的情况,但可以将其作为一种选择。

【讨论】:

  • 同样的想法,我快了一分钟,但你的答案更完整...... ;-)
  • @Lucero:花了一分钟破解打开项目文件;)
  • @Nick,我猜是这样。输入这个没有错误的东西需要一分钟左右,因为我手头没有样本,所以我只是写下了“概念”。请注意,性能方面的人可能想要添加一个字典,将枚举值映射到它们的字符串,所以这不是一个真正的问题。
  • @Sadegh:看看这里:stackoverflow.com/questions/2787506 只是使用不同的属性类型,在这种情况下是描述,但方法相同。
  • 也许您可以结合 Nick 和 Matthew 的答案来填充一次 Dictionary&lt;string,string&gt; 以减少反映电话的次数。
【解决方案2】:

关于马修的回答,我建议你使用Dictionary&lt;MyEnum, String&gt;。我将它用作静态属性:

class MyClass
{
    private static readonly IDictionary<MyEnum, String> dic = new Dictionary<MyEnum, String>
    {
        { MyEnum.EnGb, "en-gb" },
        { MyEnum.RuRu, "ru-ru" },
        ...
    };

    public static IDictionary<MyEnum, String> Dic { get { return dic; } }
}

【讨论】:

  • 如果原始值(EnGb 等)将在应用程序中传递,这很有用。不过,您应该小心公开 Dictionary getter。即使您有 readonly 引用,字典本身也是可变的。
  • @Matthew:感谢您的提示!这里有一些解决方法:stackoverflow.com/questions/678379/…。还有另一个不带 - 使财产成为internal
【解决方案3】:

如果您所有的名称/值都将完全一样,您可以像往常一样创建一个枚举。

public enum MyEnum
{
   EnGb
   FaIr
}

然后当你需要实际值时,将枚举名称作为字符串获取,将其设为小写并在中间添加-

string value = MyEnum.EnGb.ToString().ToLower().Insert(2, "-");

【讨论】:

  • 在这种特殊情况下的答案。
【解决方案4】:

没有。您可以使用Dictionary&lt;String, String&gt;。枚举的类型必须是除 char 之外的整数类型。这样可以有效地比较它们。

【讨论】:

    【解决方案5】:

    只能通过在枚举值上使用属性来间接实现,如下所示:

    public enum MyEnum {
      [DefaultValue("en-gb")]
      EnGb,
      [DefaultValue("fa-ir")]
      FaIr,
      ...
    }
    

    然后您可以通过读取枚举的静态字段上的自定义属性来使用反射检索字符串值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 2016-03-05
      相关资源
      最近更新 更多