我想知道是否有可能获得枚举值的属性,而不是枚举本身?例如,假设我有以下枚举:
using System.ComponentModel; // for DescriptionAttribute
enum FunkyAttributesEnum
{
[Description("Name With Spaces1")]
NameWithoutSpaces1,
[Description("Name With Spaces2")]
NameWithoutSpaces2
}
我想要的是给定枚举类型,产生枚举字符串值及其描述的二元组。
价值很简单:
Array values = System.Enum.GetValues(typeof(FunkyAttributesEnum));
foreach (int value in values)
Tuple.Value = Enum.GetName(typeof(FunkyAttributesEnum), value);
但我如何获得描述属性的值,以填充Tuple.Desc?如果属性属于枚举本身,我可以想到如何做到这一点,但我不知道如何从枚举的值中获得它。
这是一个使用lambda进行选择的通用实现
public static Expected GetAttributeValue<T, Expected>(this Enum enumeration, Func<T, Expected> expression)
where T : Attribute
{
T attribute =
enumeration
.GetType()
.GetMember(enumeration.ToString())
.Where(member => member.MemberType == MemberTypes.Field)
.FirstOrDefault()
.GetCustomAttributes(typeof(T), false)
.Cast<T>()
.SingleOrDefault();
if (attribute == null)
return default(Expected);
return expression(attribute);
}
这样叫它:
string description = targetLevel.GetAttributeValue<DescriptionAttribute, string>(x => x.Description);
这段代码应该为任何枚举提供了一个不错的扩展方法,使您可以检索泛型属性。我相信它与上面的lambda函数不同,因为它使用起来更简单,而且稍微-你只需要传入泛型类型。
public static class EnumHelper
{
/// <summary>
/// Gets an attribute on an enum field value
/// </summary>
/// <typeparam name="T">The type of the attribute you want to retrieve</typeparam>
/// <param name="enumVal">The enum value</param>
/// <returns>The attribute of type T that exists on the enum value</returns>
/// <example><![CDATA[string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;]]></example>
public static T GetAttributeOfType<T>(this Enum enumVal) where T:System.Attribute
{
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
return (attributes.Length > 0) ? (T)attributes[0] : null;
}
}
用法如下:
string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description;
除了AdamCrawford响应之外,我还进一步创建了一个更专门的扩展方法来获取它的描述。
public static string GetAttributeDescription(this Enum enumValue)
{
var attribute = enumValue.GetAttributeOfType<DescriptionAttribute>();
return attribute == null ? String.Empty : attribute.Description;
}
因此,要获得描述,您可以使用原始扩展方法as
string desc = myEnumVariable.GetAttributeOfType<DescriptionAttribute>().Description
或者你可以简单地调用这里的扩展方法:
string desc = myEnumVariable.GetAttributeDescription();
这应该会使您的代码更具可读性。
模型
我们用这个模型来充实我们的价值观
public class MemberTypeModel : IDto
{
public string MemberAttributeName { get; set; }
public string MemberName { get; set; }
public int MemberValue { get; set; }
}
Enum
我们的目标是枚举
public enum MemberType
{
[FieldText("Yönetim Kurul Üyesi")]
BoardManager = 0,
[FieldText("Temsilci")]
Representative = 1,
[FieldText("Üye")]
Member = 2
}
辅助方法
我们将使用helper方法来获取自定义属性对象
public T GetMemberCustomText<T>(MemberType memberType) where T : Attribute
{
var enumType = memberType.GetType();
var name = Enum.GetName(enumType, memberType);
return enumType.GetField(name).GetCustomAttributes(false).OfType<T>().SingleOrDefault();
}
Get方法
首先,我们提取枚举值并将它们转换为枚举类型。然后,通过Linq选择查询我们知道;
MemberAttributeName字段与helper方法,
带有Enum的MemberName字段。GetName方法,
将MemberValue字段转换为int类型,
我们把它填好,然后变成一个清单。
public List<MemberTypeModel> GetMemberTypes()
{
var memberTypes = Enum.GetValues(typeof(MemberType))
.Cast<MemberType>()
.Select(et => new MemberTypeModel
{
MemberAttributeName = GetMemberCustomText<FieldText>(et).Text,
MemberName = Enum.GetName(et.GetType(), et),
MemberValue = (int)et
}).ToList();
return memberTypes;
}