有许多示例可以通过自定义属性获取枚举属性,例如此处 Get Enum from Description attribute
public static class EnumEx
{
public static T GetValueFromDescription<T>(string description)
{
var type = typeof(T);
if(!type.IsEnum) throw new InvalidOperationException();
foreach(var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if(attribute != null)
{
if(attribute.Description == description)
return (T)field.GetValue(null);
}
else
{
if(field.Name == description)
return (T)field.GetValue(null);
}
}
throw new ArgumentException("Not found.", "description");
// or return default(T);
}
}
但问题是您必须对attributeType进行硬编码,即typeof(DescriptionAttribute)) as DescriptionAttribute
如何将此示例转换为通用扩展,以便我不必硬编码CustomAttributeType。
答案 0 :(得分:5)
这适用于要将值作为字符串进行比较的任何属性:
public static TEnum GetValueFromAttribute<TEnum, TAttribute>
(string text, Func<TAttribute, string> valueFunc) where TAttribute : Attribute
{
var type = typeof(TEnum);
if(!type.IsEnum) throw new InvalidOperationException();
foreach(var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field, typeof(TAttribute)) as TAttribute;
if(attribute != null)
{
if(valueFunc.Invoke(attribute) == text)
return (TEnum)field.GetValue(null);
}
else
{
if(field.Name == text)
return (TEnum)field.GetValue(null);
}
}
throw new ArgumentException("Not found.", "text");
// or return default(T);
}
然后你会这样打电话:
var value = GetValueFromAttribute<MyEnum, Description>("desc_text", a => a.Description);
答案 1 :(得分:0)
您可以添加属性实现的接口IDescription
:
public interface IDescription
{
string Description { get; }
}
public static class EnumEx
{
public static T GetValueFromDescription<T, TAttribute>(string description) where TAttribute : Attribute, IDescription
{
var type = typeof(T);
if (!type.IsEnum) throw new InvalidOperationException();
foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static))
{
var attribute = (IDescription)Attribute.GetCustomAttribute(field, typeof(TAttribute));
if (attribute != null)
{
if (attribute.Description == description)
{
return (T)field.GetValue(null);
}
}
else
{
if (field.Name == description)
{
return (T)field.GetValue(null);
}
}
}
throw new ArgumentException("Not found.", "description");
// or return default(T);
}
}
或等同于完整的基类:
public abstract class BaseDescriptionAttribute : Attribute
{
public string Description { get; protected set; }
}
public static class EnumEx
{
public static T GetValueFromDescription<T, TAttribute>(string description) where TAttribute : BaseDescriptionAttribute
{
var type = typeof(T);
if (!type.IsEnum) throw new InvalidOperationException();
foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static))
{
var attribute = (BaseDescriptionAttribute)Attribute.GetCustomAttribute(field, typeof(TAttribute));
答案 2 :(得分:0)
添加新的通用类型
public static T GetValueFromDescription<T, K>(string description)
并在GetCustomerAttribute
中使用它var attribute = Attribute.GetCustomAttribute(field, typeof(K));