2010-11-22 18 views
10

Nous avons un composant commun dans notre source qui contient toutes les énumérations (environ 300!) Pour une très grande application.C# ou VB.NET - Itérer toutes les énumérations publiques

Est-il possible, en utilisant C# ou VB.NET, d'effectuer une itération sur chacun d'entre eux afin d'effectuer une action sur chacun d'eux?

La question How to iterate all “public string” properties in a .net class est presque pertinent, mais les énumérations que je traite sont un mélange de types

Répondre

16

Quelque chose dans ce sens?

var query = Assembly.GetExecutingAssembly() 
        .GetTypes() 
        .Where(t => t.IsEnum && t.IsPublic); 

foreach (Type t in query) 
{ 
    Console.WriteLine(t); 
} 
+0

Je vais aller travailler (en utilisant 'var a = Assembly.Load (" MyAssembly ");' et 'var query = a.GetTypes(). Où (t => t.IsEnum && t.IsPublic); comment puis-je les utiliser? tous les 't' sont de type' System.RuntimeType' et je veux les utiliser comme Enums (très nouveau pour tout ce truc de réflexion!) – Shevek

+0

@Shevek: C'est une question complètement différente. Que voulez-vous exactement faire avec tous ces différents enums? – LukeH

+0

J'ai besoin d'itérer chacun des Enums et de générer un script d'insertion SQL pour créer une table de recherche – Shevek

2

Une fois que tous vos assemblages sont chargés, vous pouvez itérer à travers chaque Assemblée et appeler GetTypes() pour renvoyer tous types (vous pouvez également obtenir des types privés, bien que cela prenne plus de temps). Vous pouvez filtrer les types par IsEnum pour obtenir uniquement ceux qui sont des types enum. Notez que cela retournera également tous les types Enum de BCL. Si vous ne voulez pas les types BCL, vous devrez les filtrer. Vous pouvez vous débarrasser de la plupart d'entre eux en ignorant les assemblys dont les noms commencent par "System". Alternativement, vous pouvez vérifier que le chemin contient votre chemin local, en supposant que tous vos assemblys de projet sont locaux à votre EXE.

3

Cela devrait vous aider à démarrer. Itérer à travers les types dans les assemblées chargées; et vérifiez s'il s'agit d'une énumération:

List<string> enumValues = new List<string>(); 
foreach(Type t in AppDomain.CurrentDomain.GetAssemblies().Select(a=>a.GetTypes().Where(t=>t.IsEnum))) 
{ 
    enumValues.AddRange(Enum.GetNames(t)); 
} 
+1

Cela provoque une erreur d'exécution: 'Impossible de convertir un objet de type 'WhereArrayIterator'1 [System.Type]' pour taper 'System.Type' .' – Shevek

+0

+1 car votre '.AddRange' m'a beaucoup aidé dans ma solution! – Shevek

+2

@Shevek J'ai la même exception. En fait, j'ai trouvé cette question lorsque je cherchais la cause de cette exception dans un autre contexte. Ceci est résolu en remplaçant Select par SelectMany. J'ai mis à jour la réponse. –

2

En supposant que vous disposez de l'ensemble sur lequel les énumérations résident.

IEnumerable<Type> enums = assembly.GetTypes.Where(t => t.IsEmum); 
1

Si vous avez toutes les enums compilé dans une enum commune, vous pouvez utiliser quelque chose le long des lignes de celle-ci:

using System; 

namespace SomeApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      foreach(MyEnum target in Enum.GetValues(typeof(MyEnum))) 
      { 
       Console.WriteLine(target.ToString()); 
       // You can obviously perform an action on each one here. 
      } 
     } 
    } 

    enum MyEnum 
    { 
     One, 
     Two, 
     Three, 
     Four, 
     Five 
    }; 
} 

/* 
Prints... 

One 
Two 
Three 
Four 
Five 
*/ 

Espérons que cela peut vous aider à démarrer sur le bon chemin.