所以我需要从List<string>
enum
这是我到目前为止所做的:
枚举定义
[Flags]
public enum ContractorType
{
[Description("Recipient")]
RECIPIENT = 1,
[Description("Deliver")]
DELIVER = 2,
[Description("Recipient / Deliver")]
RECIPIENT_DELIVER = 4
}
HelperClass,提供我需要的方法:
public static class EnumUtils
{
public static IEnumerable<string> GetDescrptions(Type enumerator)
{
FieldInfo[] fi = enumerator.GetFields();
List<DescriptionAttribute> attributes = new List<DescriptionAttribute>();
foreach (var i in fi)
{
try
{
yield return attributes.Add(((DescriptionAttribute[])i.GetCustomAttributes(
typeof(DescriptionAttribute),
false))[0]);
}
catch { }
}
return new List<string>{"empty"};
}
}
现在在yield
值的行中,我得到了NullReferenceException
。我错过了什么?语法对我来说很好,但也许我忽略了什么?
修改 我在这里使用.net Framework 4.0。
答案 0 :(得分:4)
这是一个小型可重用解决方案。这是一个抽象类,它将从 T 类型中提取 K 类型的所有属性。
abstract class AbstractAttributes<T, K>
{
protected List<K> Attributes = new List<K>();
public AbstractAttributes()
{
foreach (var member in typeof(T).GetMembers())
{
foreach (K attribute in member.GetCustomAttributes(typeof(K), true))
Attributes.Add(attribute);
}
}
}
如果我们现在只想提取DescriptionAttribute
类型的属性,我们将使用以下类。
class DescriptionAttributes<T> : AbstractAttributes<T, DescriptionAttribute>
{
public List<string> Descriptions { get; set; }
public DescriptionAttributes()
{
Descriptions = Attributes.Select(x => x.Description).ToList();
}
}
此类将仅从类型DescriptionAttribute
中提取T
类型的属性。但要在您的上下文中实际使用此类,您只需执行以下操作。
new DescriptionAttributes<ContractorType>().Descriptions.ForEach(x => Console.WriteLine(x));
这行代码将写出您在DescriptionAttribute
类型的属性中用作参数的所有描述。如果您需要提取其他一些属性,只需创建一个派生自AbstractAttributes<T, K>
类的新类,并使用适当的属性关闭其类型K
。
答案 1 :(得分:2)
您需要在每个字段上找到DescriptionAttribute
(如果存在),然后检索Description
属性,例如
return enumType.GetFields()
.Select(f => (DescriptionAttribute)f.GetCustomAttribute(typeof(DescriptionAttribute)))
.Where(a => a != null)
.Select(a => a.Description)
如果您可以在字段上有多个描述,则可以执行以下操作:
FieldInfo[] fields = enumType.GetFields();
foreach(FieldInfo field in fields)
{
var descriptionAttributes = field.GetCustomAttributes(false).OfType<DescriptionAttribute>();
foreach(var descAttr in descriptionAttributes)
{
yield return descAttr.Description;
}
}
与您现有的方法更相似。
答案 2 :(得分:2)
这个通用的静态方法可以很好地获取枚举类型为T的每个值的描述列表:
public static IEnumerable<string> GetDescriptions<T>()
{
var attributes = typeof(T).GetMembers()
.SelectMany(member => member.GetCustomAttributes(typeof (DescriptionAttribute), true).Cast<DescriptionAttribute>())
.ToList();
return attributes.Select(x => x.Description);
}
答案 3 :(得分:1)
我创建了这些扩展方法
public static class EnumExtender
{
public static string GetDescription(this Enum enumValue)
{
string output = null;
Type type = enumValue.GetType();
FieldInfo fi = type.GetField(enumValue.ToString());
var attrs = fi.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
if (attrs.Length > 0) output = attrs[0].Description;
return output;
}
public static IDictionary<T, string> GetEnumValuesWithDescription<T>(this Type type) where T : struct, IConvertible
{
if (!type.IsEnum)
{
throw new ArgumentException("T must be an enumerated type");
}
return type.GetEnumValues()
.OfType<T>()
.ToDictionary(
key => key,
val => (val as Enum).GetDescription()
);
}
}
用法
var stuff = typeof(TestEnum).GetEnumValuesWithDescription<TestEnum>();
将返回值为Dictionary<TestEnum, string>
的值作为键和描述作为值。如果您只想要一个列表,可以将.ToDictionary
更改为
.Select(o => (o as Enum).GetDescription())
.ToList()
答案 4 :(得分:0)
它认为这可以解决您的问题。如果未实现,您可以返回null
或例外。这取决于你的需要。
public DescriptionAttribute GetDescription(ContractorType contractorType)
{
MemberInfo memberInfo = typeof(ContractorType).GetMember(contractorType.ToString())
.FirstOrDefault();
if (memberInfo != null)
{
DescriptionAttribute attribute = (DescriptionAttribute)
memberInfo.GetCustomAttributes(typeof(DescriptionAttribute), false)
.FirstOrDefault();
return attribute;
}
//return null;
//or
throw new NotImplementedException("There is no description for this enum");
}
所以你会像这样使用它:
DescriptionAttribute attribute = GetDescription(ContractorType.RECIPIENT);
很抱歉,我没有看到您的问题。以下是一些可用于获取所有描述字符串的代码:
public IEnumerable<string> GetAllDescriptionInText()
{
List<string> descList = new List<string>();
foreach (DescriptionAttribute desc in Enum.GetValues(typeof(DescriptionAttribute)))
{
descList.Add(GetDescription(desc).Value);
}
return descList;
}
答案 5 :(得分:0)
你可以试试这个
public string ContractorTypeDescription(Enum ContractorType)
{
FieldInfo fi = ContractorType.GetType().GetField(ContractorType.ToString());
var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
return attributes[0].Description;
}
else
{
return ContractorType.ToString();
}
}
答案 6 :(得分:0)
这是字典而不是列表
但是我使用的是
using System.ComponentModel;
using System.Reflection;
using MyExtensions;
namespace MyExtensions
{
public static class Extension
{
public static string GetDescriptionName(this Enum value)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (name == null)
return null;
else
{
FieldInfo field = type.GetField(name);
if (field == null)
return name;
else
{
DescriptionAttribute attr =
Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attr == null)
return name;
else
return attr.Description;
}
}
}
}
}
namespace EnumDescription
{
class Program
{
public enum enumDateCond : byte
{
[Description("Empty")]
Null = 0,
[Description("Not Empty")]
NotNull = 1,
EQ = 2,
LT = 3,
LE = 4,
GE = 14,
GT = 15
};
static void Main(string[] args)
{
enumDateCond x = enumDateCond.Null;
string description = x.GetDescriptionName();
foreach (enumDateCond enm in Enum.GetValues(typeof(enumDateCond)))
{
description = enm.GetDescriptionName();
Console.WriteLine(description);
}
Console.WriteLine("Dictionary");
Dictionary<enumDateCond, string> DLenumDateCond = EnumToDictionary<enumDateCond>();
foreach(enumDateCond key in DLenumDateCond.Keys)
{
Console.WriteLine(key.ToString() + " " + DLenumDateCond[key]);
}
}
public static Dictionary<T, string> EnumToDictionary<T>()
where T : struct
{
Type enumType = typeof(T);
// Can't use generic type constraints on value types,
// so have to do check like this
if (enumType.BaseType != typeof(Enum))
throw new ArgumentException("T must be of type System.Enum");
Dictionary<T, string> enumDL = new Dictionary<T, string>();
foreach (T enm in Enum.GetValues(enumType))
{
string name = Enum.GetName(enumType, enm);
if (name != null)
{
FieldInfo field = enumType.GetField(name);
if (field != null)
{
DescriptionAttribute attr =
Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attr != null)
name = attr.Description;
}
}
enumDL.Add(enm, name);
}
return enumDL;
}
}
}