2009-03-26 17 views
17

Ich bin ein absoluter Neuling bei Reflexion in C#. Ich möchte mit Reflection auf alle privaten Felder einer Klasse zugreifen, einschließlich derer, die vererbt werden.C#: Zugriff auf vererbte private Instanz Mitglieder durch Reflexion

Es ist mir gelungen, auf alle privaten Felder zuzugreifen, ausgenommen diejenigen, die vererbt werden, sowie alle öffentlichen und geschützten geerbten Felder. Ich konnte jedoch nicht auf die privaten, geerbten Felder zugreifen. Das folgende Beispiel zeigt:

class A 
{ 
    private string a; 
    public string c; 
    protected string d; 
} 

class B : A 
{ 
    private string b; 
} 

class test 
{ 
    public static void Main(string[] Args) 
    { 
     B b = new B();  
     Type t; 
     t = b.GetType(); 
     FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic 
             | BindingFlags.Instance); 
     foreach(FieldInfo fi in fields){ 
      Console.WriteLine(fi.Name); 
     } 
     Console.ReadLine(); 
    } 
} 

Dies kann das Feld B.a.

Ist das überhaupt möglich? Die naheliegende Lösung wäre, die privaten, geerbten Felder in geschützte Felder umzuwandeln. Dies ist jedoch im Moment außer Kontrolle.

Antwort

14

Wie Lee sagte, können Sie dies mit Rekursion tun.

private static void FindFields(ICollection<FieldInfo> fields, Type t) { 
    var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; 

    foreach (var field in t.GetFields(flags)) { 
     // Ignore inherited fields. 
     if (field.DeclaringType == t) 
      fields.Add(field); 
    } 

    var baseType = t.BaseType; 
    if (baseType != null) 
     FindFields(fields, baseType); 
} 

public static void Main() { 
    var fields = new Collection<FieldInfo>(); 
    FindFields(fields, typeof(B)); 
    foreach (FieldInfo fi in fields) 
     Console.WriteLine(fi.DeclaringType.Name + " - " + fi.Name); 
} 
+0

Anstelle der "if" -Klausel, um vererbte Felder zu ignorieren, können Sie BindingFlags.DeclaredOnly angeben. – Timwi

+0

ohne Verwendung von BaseType für einen Type, können wir weiterhin auf private Member der Basisklasse zugreifen. Nein, das löst kein wirkliches Problem für mich, aber ich bin nur neugierig, weil ich mit der BaseType-Eigenschaft der Type-Klasse davon ausgehe, dass ich (während ich es schreibe) auf Childs-Basisklassenmitglieder zugreife BaseType-Eigenschaft, um das gleiche zu erreichen? – Zenwalker

0

Sie können die privaten Felder von A Zugriff auf die Art der B verwenden, da diese Felder nicht existieren in B - sie existieren nur in A. Sie müssen entweder den Typ A direkt angeben oder sie auf andere Weise abrufen (z. B. das Abrufen der Basisklasse vom Typ B).

+3

Müll, natürlich sind sie in B. vor, wenn sie nicht in B waren, wie ein Verfahren von A geerbt könnte, die Zugriff auf eine solche privaten Feldarbeit ? – Timwi

+4

Die Instanz von B kann die privaten Mitglieder von A haben, aber der Typ von B kennt solche Mitglieder nicht. – Andy

4

Ich habe es nicht versucht, aber Sie sollten in der Lage sein, auf die privaten Mitglieder des Basistyps über die Type.BaseType-Eigenschaft zuzugreifen und rekursiv alle privaten Felder durch die Vererbung-Hierarchie zu akkumulieren.

-1

Sie private Mitglieder der Klasse A aus der Klasse B mit 'Nested Classes' zugreifen können. Sie machen der Klasse A als Outer-Klasse und der Klasse B als innere Klasse

Class A 
{ 
... 
Class B 
{ 
....... 
    } 

} 
+2

Ich bin nicht in der Lage, die Klassen zu ändern. Ich versuche nur Informationen über sie durch Reflexion zu sammeln. – Odrade

Verwandte Themen