Невозможно получить тип enum, если определение находится внутри класса через отражение - PullRequest
0 голосов
/ 18 февраля 2020

Как получить тип перечисления, если перечисление определено внутри класса?

Адаптировано из кода здесь :

namespace GetEnumReflectionTesting
{
    enum Foo { Bar = 5 }
    public class MyClass
    {
        enum Foo { Bar =6}
    }


    class Program
    {
        static void Main()
        {
            // Get the assembly containing the enum - Here it's the one executing
            var assembly = Assembly.GetExecutingAssembly();


            var enumType = assembly.GetType("GetEnumReflectionTesting.Foo"); //this obtains the GetEnumReflectionTesting.Foo
            var enumBarValue = enumType.GetField("Bar").GetValue(null);
            Console.WriteLine("{0}|{1}", enumBarValue, (int)enumBarValue);

            var enumType2 = assembly.GetType("GetEnumReflectionTesting.MyClass.Foo"); //but instead of GetEnumReflectionTesting.MyClass.Foo, this returns a null!
            var enumBarValue2 = enumType2.GetField("Bar").GetValue(null);
            Console.WriteLine("{0}|{1}", enumBarValue2, (int)enumBarValue2);
        }
    }
}

Вот кое-что интересное, enumType возвращает GetEnumReflectionTesting.Foo, как и ожидалось, но enumType2 вместо получения GetEnumReflectionTesting.MyClass.Foo возвращает null!

Итак, каков надежный способ получить тип перечисления независимо от того, определен он в классе или нет?

Обратите внимание, что в моем сценарии перечисление Foo определено внутри класс, и я получаю его от стороннего поставщика, который я не могу изменить. Поэтому не предлагайте мне перенести перечисление Foo за пределы класса.

1 Ответ

1 голос
/ 18 февраля 2020

Используйте +, чтобы отделить имя класса верхнего уровня от имени вложенного класса:

var enumType2 = assembly.GetType("GetEnumReflectionTesting.MyClass+Foo");
// ...............................................................^

var enumBarValue2 = enumType2.GetField("Bar").GetValue(null);
Console.WriteLine("{0}|{1}", enumBarValue2, (int)enumBarValue2);

Это приведет к:

Bar|6

Другой способ сделать это, чтобы получить тип верхнего уровня и затем вызвать GetNestedType для него.

var containingType2 = assembly.GetType("GetEnumReflectionTesting.MyClass");
var enumType2 = containingType2.GetNestedType("Foo", BindingFlags.NonPublic);
var enumBarValue3 = enumType2.GetField("Bar").GetValue(null);
Console.WriteLine("{0}|{1}", enumBarValue3, (int)enumBarValue3);

Обратите внимание, что вы должны использовать Bindingflags.NonPublic, потому что способ, которым вы определили вложенный Foo enum является неявным образом закрытым. Если используемая вами библиотека имеет вложенный тип public, этот параметр можно опустить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...