【问题标题】:Access Enum custom attributes whilst looping over values在遍历值的同时访问枚举自定义属性
【发布时间】:2013-12-05 17:01:09
【问题描述】:

我为一些枚举值添加了一个自定义属性(给它们一个屏幕友好的字符串值)。我正在尝试构建一个在 MVC 页面上使用的 SelectListItems 列表,但我在访问自定义属性时遇到了麻烦。

我的枚举看起来像这样。

public enum MyEnum
{
   [StringValue("None")] None = 0,
   [StringValue("First Value")] FirstValue = 1,
   [StringValue("Second Value")] SecondValue = 2
}

属性如下所示。

public class StringValueAttribute : Attribute 
{
    public StringValueAttribute(string value)
    {
        this.StringValue = value;
    }

    public string StringValue { get; protected set; }        
}

我创建了一个辅助类,以便我可以轻松地从 Enum 的实例访问 StringValue 属性。

public static string GetStringValue(this Enum value)
{
    Type type = value.GetType();
    FieldInfo fieldInfo = type.GetField(value.ToString());
    StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
    return attribs != null && attribs.Length > 0 ? attribs[0].StringValue : null;
}

我可以这样称呼它。

MyEnum test = MyEnum.FirstValue;
string stringValue = test.GetStringValue();

最后,我坚持的代码。我可以轻松地遍历枚举值,但这些值不是 MyEnum 的实例,因此我无法调用我的辅助函数。当我尝试访问 FieldInfo 时,它总是返回 null。这是我目前所拥有的。

public static List<SelectListItem> GetFlagsSelectList<T>(int? selectedValue)
{
    List<SelectListItem> items = new List<SelectListItem>();
    foreach (int value in Enum.GetValues(typeof(T)))
    {
        items.Add(new SelectListItem
        {
            Text = Enum.GetName(typeof(T), value), 
            Value = value.ToString(), 
            Selected = selectedValue.HasValue && selectedValue.Value == value
        });
    }
    return items;
}

是否可以在 foreach 循环中访问自定义属性?

编辑:

我想我问的不清楚。我想访问 foreach 循环内的自定义属性。调用 Enum.GetName(typeof(T), value) 只会返回我不想要的属性的名称(例如 FirstValue)。

我想做这样的事情:

foreach (int value in Enum.GetValues(typeof(T)))
{
    string name = Enum.ToObject(typeof (T), value).GetStringValue();
}

但是 T 可以是任何类型,所以我不能在那里调用我的 GetStringValue() 方法。

我试过这样做:

foreach (int value in Enum.GetValues(typeof(T)))
{
    FieldInfo fieldInfo = typeof(T).GetField(value.ToString());
    StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
    string name = attribs != null && attribs.Length > 0 ? attribs[0].StringValue : Enum.GetName(typeof(T), value),;

    items.Add(new SelectListItem
    {
        Text = name,
        Value = value.ToString(),
        Selected = selectedValue.HasValue && selectedValue.Value == value
    });
}

但我总是遇到异常,因为 FieldInfo 对象总是返回 null。

【问题讨论】:

    标签: c# enums custom-attributes


    【解决方案1】:

    试试

    static string GetStringValue2(Enum value) {
     ....
    }
    
    public static List<SelectListItem> GetFlagsSelectList<T>(int? selectedValue) where T : struct {
      var items = new List<SelectListItem>();
      foreach (T value in Enum.GetValues(typeof(T))) {
        var stringValue = GetStringValue2((Enum)(object)value);
        items.Add(new SelectListItem {
          Text = Enum.GetName(typeof(T), value),
          Value = Convert.ToInt32(value).ToString(),
          Selected = selectedValue.HasValue && selectedValue.Value == Convert.ToInt32(value)
        });
      }
      return items;
    }
    

    【讨论】:

    • 非常感谢,抱歉在我发布更新之前没有看到您的编辑。
    【解决方案2】:

    不久前我写了一封blog post 来讨论这个问题(XmlEnumAttribute,但这里同样适用)。

    public static string ConvertToString(Enum e)
    {
      // Get the Type of the enum
      Type t = e.GetType();
    
      // Get the FieldInfo for the member field with the enums name
      FieldInfo info = t.GetField(e.ToString("G"));
    
      // Check to see if the XmlEnumAttribute is defined on this field
      if (!info.IsDefined(typeof(XmlEnumAttribute), false))
      {
        // If no XmlEnumAttribute then return the string version of the enum.
        return e.ToString("G");
      }
    
      // Get the XmlEnumAttribute
      object[] o = info.GetCustomAttributes(typeof(XmlEnumAttribute), false);
      XmlEnumAttribute att = (XmlEnumAttribute)o[0];
      return att.Name;
    }
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-22
      • 2010-12-12
      • 2017-04-02
      • 1970-01-01
      • 2019-09-13
      • 1970-01-01
      • 1970-01-01
      • 2011-07-03
      相关资源
      最近更新 更多