2013-03-12 13 views
14

Ho una classe statica che contiene molte classi statiche. Ogni classe statica interna contiene campi. Voglio ottenere tutti i campi di tutte le classi statiche interne.Ottieni tutti i campi da classi statiche all'interno della classe statica con riflessione

public static class MyClass 
{ 
    public static class MyInnerClass1 
    { 
     public const string Field1 = "abc"; 
     public const string Field2 = "def"; 
     public const string Field3 = "ghi"; 
    } 
    public static class MyInnerClass2 
    { 
     public const int Field1 = 1; 
     public const int Field2 = 2; 
     public const int Field3 = 3; 
    } 
    ... 
} 

Vorrei stampare il nome di ogni classe interna seguito dal nome e il valore di ogni campo.

Ad esempio:

MyInnerClass

Field1 = "abc"

...

Non ho alcun problema con ottenere il nome di tutte le classi:

var members = typeof(MyClass).GetMembers(BindingFlags.Public | BindingFlags.Static); 

var str = ""; 
foreach (var member in members) 
{ 
    str += member.Name +" ";    
} 

O il nome e il valore di tutti i campi in una specifica classe:

var fields = typeof(MyClass.MyInnerClass1).GetFields(); 
foreach (var field in fields) 
{ 
    str += field.Name + "-"; 
    str += field.GetValue(typeof(MyClass.MyInnerClass1)); 
} 

Ma come faccio a combinare questo? I nomi e il numero di classi statiche interne possono cambiare.

risposta

16

provare il seguente

var builder = new StringBuilder(); 
foreach (var type in typeof(MyClass).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic)) 
{ 
    if (!type.IsAbstract) 
    { 
    continue; 
    } 

    builder.AppendLine(type.Name); 
    foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) { 
    var msg = String.Format("{0} = {1}", field.Name, field.GetValue(null)); 
    builder.AppendLine(msg); 
    } 
} 

string output = builder.ToString(); 

L'uso di !type.IsAbstract è fatto per erbaccia sui tipi nidificati non statici. Un tipo statico in C# viene generato come abstract sotto il cofano.

Anche la mia soluzione raccoglierà sia public sia membri non pubblici (entrambi i tipi e campi). Non sono sicuro che questa fosse la tua intenzione o no, quindi potresti voler modificare quella parte della mia soluzione.

9

È necessario ciclo ricorsivo attraverso type.GetNestedTypes():

IEnumerable<FieldInfo> GetAllFields(Type type) { 
    return type.GetNestedTypes().SelectMany(GetAllFields) 
       .Concat(type.GetFields()); 
} 
Problemi correlati