2015-09-23 3 views
3

Рассмотрим следующий C# объявление класса:Получить тип перечисления в .NET класса

public class MyClass { 
    private enum Colours { Red, Green, Blue } 
} 

Который сидел в отдельном классе библиотеки/DLL.

Как только объект typeof (MyClass) (System.Type), есть ли способ проверить, содержит ли класс enum, называемый Colors во время выполнения, и если он возвращает соответствующий объект System.Type?

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

Я знаю, как использовать Reflection для запроса таких вещей, как GetFields, GetProperties и т. Д., Но в System.Type нет метода GetClasses или GetEnums.

Я подозреваю, что такая информация находится в сборке?

+0

А также, когда у меня есть System.Type из перечисление, я знаю, как запрашивать значения. Он получает информацию о самом перечислении, это сложный бит –

+4

['GetNestedType'] (https://msdn.microsoft.com/library/system.type.getnestedtype.aspx) – PetSerAl

+0

Doh! Это может быть ... позже! –

ответ

8

Вобще:

var res = typeof(MyClass).GetNestedType("Colours", BindingFlags.NonPublic); 

тест res != null, чтобы увидеть, если такой тип существует.

Затем проверьте res.IsEnum, чтобы узнать, является ли вложенный тип переименованием.

Дополнение: Если вложенный тип изредка является вложенным, используйте вместо него BindingFlags.NonPublic | BindingFlags.Public.

+0

Спасибо, что только билет. Я прошел через методы в System.Type, и мои глаза, должно быть, застекляли это. Очевидно, действительно –

+0

Да, вероятно, лучше всего проверить общедоступные перечисления –

0
var types = typeof(MyClass).Assembly.DefinedTypes; 

foreach (var type in types) 
{ 
    Console.WriteLine(type.Name); 
} 

Выходные:

MyClass
Цвета

+1

Это приведет к поиску во всей сборке, где определен '' MyClass''. Я сомневаюсь, что это предназначенное решение - «есть ли способ проверить, содержит ли класс перечисление, называемое Colors во время выполнения» –

2

я придумал следующие два метода:

public class MyClass { 
    private enum Colours { Red, Green, Blue } 

    private class Inner { 
     private enum Colours { Black, White } 
    } 
} 

class Program { 
    static void Main(string[] args) { 
     Type coloursType; 
     // 1. enumerator 
     coloursType = typeof(MyClass).EnumerateNestedTypes() 
      .Where(t => t.Name == "Colours" && t.IsEnum) 
      .FirstOrDefault(); 
     // 2. search method 
     coloursType = typeof(MyClass).FindNestedType(t => t.Name == "Colours" && t.IsEnum); 

     if(coloursType != null) { 
      Console.WriteLine(string.Join(", ", coloursType.GetEnumNames())); 
     } else { 
      Console.WriteLine("Type not found"); 
     } 
     Console.ReadKey(); 
    } 
} 

public static class Extensions { 
    public static IEnumerable<Type> EnumerateNestedTypes(this Type type) { 
     const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic; 
     Queue<Type> toBeVisited = new Queue<Type>(); 
     toBeVisited.Enqueue(type); 
     do { 
      Type[] nestedTypes = toBeVisited.Dequeue().GetNestedTypes(flags); 
      for(int i = 0, l = nestedTypes.Length; i < l; i++) { 
       Type t = nestedTypes[i]; 
       yield return t; 
       toBeVisited.Enqueue(t); 
      } 
     } while(toBeVisited.Count != 0); 
    } 

    public static Type FindNestedType(this Type type, Predicate<Type> filter) { 
     const BindingFlags flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic; 
     Type[] nestedTypes = type.GetNestedTypes(flags); 
     foreach(var nestedType in nestedTypes) { 
      if(filter(nestedType)) { 
       return nestedType; 
      } 
     } 
     foreach(var nestedType in nestedTypes) { 
      Type result = FindNestedType(nestedType, filter); 
      if(result != null) { 
       return result; 
      } 
     } 
     return null; 
    } 
} 
Смежные вопросы