我在十几种不同的解决方案中编写了以下方法的某些版本:
//Get the string specified in the "Description" attribute of an enum value
public static string GetDescription<T>(this T enumVal) where T : Enum
{
var type = enumVal.GetType();
var member = type.GetMember(enumVal.ToString()).First();
var attrib = member.GetCustomAttribute<DescriptionAttribute>();
return attrib?.Description ?? null;
}
给出这个枚举:
public enum MyEnum
{
[Description("The First")] TheFirst,
[Description("The Second")] TheSecond
}
然后我可以编写以下代码:
MyEnum.TheFirst.GetDescription()
>> "The First"
此方法有效,这是我见过人们的唯一方法。这是我的问题:
如何在不使用MemberInfo
来迭代类型成员以匹配字符串的情况下获得Type.GetMember()
?如果输入(MyEnum.TheFirst
已经是一个非常合格的成员,为什么反射要求我放弃它,并且本质上将它作为字符串搜索?
我想要要编写的代码是:
public static string GetDescription<T>(this T enumVal) where T : Enum
{
var member = enumVal.GetMember(); //gets the fully qualified MemberInfo object
var attrib = member.GetCustomAttribute<DescriptionAttribute>();
return attrib?.Description ?? null;
}
我知道我可以编写一个扩展方法来执行此操作,但是它不能解决根本的问题:我必须使用string
搜索(同样,通过System.Reflection.GetMember(string name)
方法)只是为了获取应该已经可用的信息。
请让我知道,如果我想的是错误的方法,或者是否有另一种更简单的方法。
答案 0 :(得分:1)
很难回答“为什么不”的问题,所以让我们考虑一下您想要的功能的存在所需要的条件。必须对其进行考虑,设计,实施,测试和记录。可以将大量精力花费在优先级更高的功能上,这些功能将为用户带来更大的影响和更大的实用性。
这是高优先级功能吗?人们是否大部分时间都想从枚举的当前值中获取该枚举的类型成员?这是他们无法使用现有的反射API轻松完成的事情吗?
我倾向于对所有这些都拒绝,特别是因为您可以用两行代码实现想要做的事情,而不会明显降低生产力或性能。
此外,从设计反射方法以首先获得成员的角度考虑这一点。您希望能够从 any 类型获得 any 成员,而不仅仅是枚举。您希望支持最有用和最通用的情况,以便为用户提供最大的价值,因此获取成员的最直接方法是按其名称。这意味着搜索字符串。
是否有足够多的情况用户想要传递枚举值并获取其对应成员,以至于需要某种特殊情况来支持枚举而不通过标准名称搜索API?我也倾向于拒绝。
答案 1 :(得分:0)
如果您愿意指定唯一传入的Enum
值将来自使用默认值声明的Enum
,因此它基于Int32
和顺序值,则可以做
public static string GetDescription<T>(this T enumVal) where T : Enum {
var type = enumVal.GetType();
var memberInfo = type.GetFields()[1+Convert.ToInt32(enumVal)];
var attrib = memberInfo.GetCustomAttribute<DescriptionAttribute>();
return attrib?.Description ?? null;
}