Получить MemberInfo члена типа без итерации всех членов типа - PullRequest
0 голосов
/ 01 мая 2019

Я написал некоторую версию следующего метода в дюжине различных решений:

//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) уже является строго квалифицированным членом, почему рефлексия требует от меня отказаться от него и, по сути, искать элемент в виде строки?

Код I , который требуется длянапишите:

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 ]

1 голос
/ 01 мая 2019

Трудно ответить на вопросы «почему бы и нет», поэтому давайте подумаем о том, что потребуется для того, чтобы вместо этого существовала желаемая функция. Это должно быть продумано, спроектировано, реализовано, протестировано и задокументировано. Это большое количество усилий, которое можно потратить на функции с более высоким приоритетом, которые обеспечат более высокую отдачу и большую полезность для пользователя.

Это высокоприоритетная функция? Желают ли люди получить типовой член перечисления из его текущего значения в большинстве случаев? Это то, что они не могли легко сделать с существующим API отражения?

Я бы предпочел сказать "нет" всем этим, особенно потому, что вы можете достичь того, что вы хотите сделать, в двух строках кода без видимой потери производительности или производительности.

Кроме того, подумайте об этом с точки зрения разработки метода отражения, чтобы получить элемент в первую очередь. Вы хотите иметь возможность получить любой член из любого типа, а не просто перечисление. Вы хотите поддержать самый полезный и самый общий случай, чтобы обеспечить наибольшую ценность для пользователя, поэтому самый простой способ получить член - это его имя. Это означает поиск строки.

Достаточно ли случаев, когда пользователь хочет передать значение перечисления и получить его соответствующий член, и так много, что требуется особый случай для поддержки перечислений без прохождения стандартного API поиска имен? Я также склонен сказать "нет" на это.

0 голосов
/ 02 мая 2019

Если вы хотите указать, что единственные переданные в Enum значения будут из Enum s, объявленных со значениями по умолчанию, поэтому он основан на 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...