关于c#:在循环值时访问枚举自定义属性

Access Enum custom attributes whilst looping over values

我为一些枚举值添加了一个自定义属性(为它们提供一个屏幕友好的字符串值)。我正试图构建一个用于MVC页面的selectListItem列表,但访问自定义属性时遇到问题。

我的枚举看起来像这样。

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

属性如下。

1
2
3
4
5
6
7
8
9
public class StringValueAttribute : Attribute
{
    public StringValueAttribute(string value)
    {
        this.StringValue = value;
    }

    public string StringValue { get; protected set; }        
}

我创建了一个助手类,这样我就可以轻松地从枚举的实例访问StringValue属性。

1
2
3
4
5
6
7
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;
}

我可以这样称呼它。

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

最后,回到我一直坚持的代码上。我可以轻松地循环枚举值,但这些值不是my enum的实例,因此我无法调用helper函数。当我尝试访问fieldinfo时,它总是返回空值。这是我到目前为止所拥有的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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)的名称。

我想做如下的事情:

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

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

我试过这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
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对象总是返回空值。


尝试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}


不久前我写了一篇关于这个的博客(对于XmlEnumAttribute),但这里同样适用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
}

希望有帮助。