在遍历值的同时访问枚举自定义属性
Posted
技术标签:
【中文标题】在遍历值的同时访问枚举自定义属性【英文标题】: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。
【问题讨论】:
【参考方案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;
希望对您有所帮助。
【讨论】:
以上是关于在遍历值的同时访问枚举自定义属性的主要内容,如果未能解决你的问题,请参考以下文章