获取类型成员的MemberInfo,而无需迭代所有类型成员

时间:2019-05-01 15:19:34

标签: c# reflection

我在十几种不同的解决方案中编写了以下方法的某些版本:

//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)方法)只是为了获取应该已经可用的信息。

请让我知道,如果我想的是错误的方法,或者是否有另一种更简单的方法。

2 个答案:

答案 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;
}