通过自定义属性获取枚举(通用)
Get Enum by Custom Attribute (Generic)
有很多示例,您可以像这里一样通过自定义属性获取枚举
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);
}
}
但这里的问题是您必须对属性类型进行硬编码,即 typeof(DescriptionAttribute)) as DescriptionAttribute
如何将此示例转换为通用扩展,以便不必对 CustomAttributeType 进行硬编码。
这适用于您想要将值作为字符串进行比较的任何属性:
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);
您可以添加一个接口 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);
}
}
或等价于完整的基础 class:
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));
添加新的泛型类型
public static T GetValueFromDescription<T, K>(string description)
并在 GetCustomerAttribute
中使用它
var attribute = Attribute.GetCustomAttribute(field, typeof(K));
有很多示例,您可以像这里一样通过自定义属性获取枚举 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);
}
}
但这里的问题是您必须对属性类型进行硬编码,即 typeof(DescriptionAttribute)) as DescriptionAttribute
如何将此示例转换为通用扩展,以便不必对 CustomAttributeType 进行硬编码。
这适用于您想要将值作为字符串进行比较的任何属性:
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);
您可以添加一个接口 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);
}
}
或等价于完整的基础 class:
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));
添加新的泛型类型
public static T GetValueFromDescription<T, K>(string description)
并在 GetCustomerAttribute
中使用它var attribute = Attribute.GetCustomAttribute(field, typeof(K));