2010-11-22 8 views
10

Wir haben eine gemeinsame Komponente in unserer Quelle haben, die die Aufzählungen enthält alle (ca. 300!) Für eine sehr große Anwendung.C# oder VB.NET - Iterate alle öffentlichen Aufzählungen

Gibt es eine Möglichkeit, entweder mit C# oder VB.NET, durch alle von ihnen, um zu durchlaufen eine Aktion auf jedem durchführen?

Die Frage How to iterate all “public string” properties in a .net class fast relevant ist, aber die Aufzählungen ich sind eine Mischung von Typen zu tun bin

Antwort

16

Etwas in dieser Richtung?

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

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

Ich gehe das zur Arbeit (mit 'var a = Assembly.Load (" MyAssembly ");' und 'var query = a.GetTypes(). Wo (t => t.IsEnum && t.IsPublic);') aber Wie benutze ich sie dann? Alle 't' sind vom Typ' System.RuntimeType' und ich möchte sie als Enums verwenden (sehr neu für all diese Reflection-Sachen!) – Shevek

+0

@Shevek: Das ist eine ganz andere Frage. Was genau willst du mit all diesen verschiedenen enums machen? – LukeH

+0

Ich muss jedes der Enums durchlaufen und ein SQL-Einfügeskript generieren, um eine Nachschlagetabelle zu erstellen – Shevek

2

Einmal geladen, alle Ihre Baugruppen sind, können Sie durch jede Assembly iterieren und GetTypes() aufrufen, alle Arten zurückzukehren (Sie können optional auch private Typen erhalten, auch wenn dies länger dauert). Sie können die Typen nach IsEnum filtern, um nur die Enum-Typen zu erhalten. Beachten Sie, dass dadurch auch alle BCL-Enum-Typen zurückgegeben werden. Wenn Sie die BCL-Typen nicht möchten, müssen Sie sie ausfiltern. Sie können die meisten davon loswerden, indem Sie Baugruppen ignorieren, deren Namen mit "System" beginnen. Alternativ können Sie überprüfen, ob der Pfad Ihren lokalen Pfad enthält, vorausgesetzt, dass alle Ihre Projektassemblys lokal für Ihre EXE sind.

3

Dies sollte Ihnen den Anfang machen. Iterieren durch die Typen in den geladenen Baugruppen; und überprüfen, ob sie eine enum sind:

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

Dies gibt einen Laufzeitfehler: 'Kann nicht Objekt vom Typ 'WhereArrayIterator'1 [System.Type]' auf Typ 'System.Type' eingeben. – Shevek

+0

+1 als Ihre' .AddRange' in meiner Lösung sehr geholfen! – Shevek

+2

@Shevek Ich habe die gleiche Ausnahme. Tatsächlich habe ich diese Frage bei der Suche nach der Ursache dieser Ausnahme in einem anderen Kontext gefunden. Dies wird durch Ersetzen von Select by SelectMany gelöst. Ich habe die Antwort aktualisiert. –

2

Angenommen, Sie haben die Assembly, auf der sich die Enums befinden.

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

Wenn Sie alle enums in einen gemeinsamen enum zusammengestellt, die Ihnen etwas entlang der Linien von dieser nutzen könnten:

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 
*/ 

Hoffentlich Sie begann den richtigen Weg bekommen kann.