2013-04-15 4 views
10

Wenn ich eine C# -Klasse haben MyClass wie folgt:Wie lese ich die internen Eigenschaften einer C# -Klasse? geschützt? geschützt intern?

using System.Diagnostics; 

namespace ConsoleApplication1 
{ 
    class MyClass 
    { 
     public int pPublic {get;set;} 
     private int pPrivate {get;set;} 
     internal int pInternal {get;set;} 
    } 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Debug.Assert(typeof(MyClass).GetProperties(
       System.Reflection.BindingFlags.Public | 
       System.Reflection.BindingFlags.Instance).Length == 1); 
      Debug.Assert(typeof(MyClass).GetProperties(
       System.Reflection.BindingFlags.NonPublic | 
       System.Reflection.BindingFlags.Instance).Length == 2); 
      // internal? 
      // protected? 
      // protected internal? 
     } 
    } 
} 

Der obige Code compiliert läuft ohne Assertionsfehler sind. NonPublic gibt die internen und privaten Eigenschaften zurück. Es scheint keine Flags für die anderen Accessibility-Typen unter BindingFlags zu geben.

Wie bekomme ich eine Liste/Array von nur die Eigenschaften, die intern sind? Auf eine verwandte Anmerkung, aber nicht notwendig für meine Anwendung, was ist geschützt oder geschützt intern?

Antwort

16

Wenn Sie die Eigenschaft Infos mit BindingFlags.NonPublic erhalten, können Sie die Getter oder Setter finden von GetGetMethod(true) und GetSetMethod(true) jeweils unter Verwendung. Anschließend können Sie die folgenden Eigenschaften überprüfen (der Methode info) die genaue Zugriffsebene zu erhalten:

  • propertyInfo.GetGetMethod(true).IsPrivate bedeutet private
  • propertyInfo.GetGetMethod(true).IsFamily Mittel geschützt
  • propertyInfo.GetGetMethod(true).IsAssembly bedeuten interne
  • propertyInfo.GetGetMethod(true).IsFamilyOrAssembly bedeutet interne geschützt

und natürlich für GetSetMethod(true) natürlich.

Denken Sie daran, dass es zulässig ist, einen der Accessoren (Getter oder Setter) eingeschränkter als den anderen zu haben. Wenn es nur einen Accessor gibt, ist dessen Zugänglichkeit die Zugänglichkeit des gesamten Eigentums. Wenn beide Accessoren da sind, gibt Ihnen die am meisten zugängliche die Zugänglichkeit der gesamten Eigenschaft.

Verwenden propertyInfo.CanRead zu sehen, ob es in Ordnung ist propertyInfo.GetGetMethod zu nennen, und verwenden Sie propertyInfo.CanWrite zu sehen, ob es in Ordnung ist propertyInfo.GetSetMethod zu nennen. Die Methoden GetGetMethod und GetSetMethod geben null zurück, wenn der Accessor nicht existiert (oder wenn er nicht öffentlich ist und Sie nach einem öffentlichen Accessor gefragt haben).

+2

Eine andere Option wäre, propertyInfo.GetGetMethod (true) aufzurufen. d. h. propertyInfo.GetGetMethod (true) .IsPrivate. Beachten Sie auch, dass ich GetProperties wie folgt aufrufen musste, damit es funktioniert GetProperties (BindingFlags.NonPublic | BindingFlags.Instance); GetProperties (BindingFlags.NonPublic) an sich hat nicht funktioniert – cgotberg

+0

@cgotberg Ja, ich habe meine Antwort bearbeitet, um 'true' Parameter zu verwenden. Sonst gibt es Ihnen nicht die nicht-öffentlichen Accessoren. Vielen Dank. –

3

GetProperties mit System.Reflection.BindingFlags.NonPublic Flagge gibt alle von ihnen: private, internal, protected und protected internal.

+0

Ich nehme an, Sie können nicht mehr granular als das bekommen. –

+0

Entschuldigung, dass ich nicht klar bin. Ich habe das Wort "nur" zu meinen Fragen hinzugefügt, um deutlich zu machen, dass ich nur solche bekommen möchte. – ryantm

+1

Sie können keine detaillierteren Daten erhalten als nur "public" oder "nonpublic". – MarcinJuraszek

6

Siehe this article auf MSDN.

Relevante Zitat:

Die C# keywords geschützt und internes hat keine Bedeutung in IL und nicht in dem Reflexions APIs verwendet. Die entsprechenden Begriffe in IL sind Familie und Montage. Verwenden Sie die IsAssembly-Eigenschaft, um eine interne Methode zu identifizieren, die Reflektion verwendet . Verwenden Sie zum Identifizieren einer geschützten internen Methode das IsFamilyOrAssembly.

+0

Das sind nur Methoden oder auch Eigenschaften? – MarcinJuraszek

+0

Ich glaube nicht, dass es einen Unterschied gibt. –

+0

Ich denke, es gibt, weil sowohl 'IsAssembly' und 'IsFamilyAndAssembly' in der 'MethodBase' Klasse deklariert sind, so dass sie nicht auf' PropertyInfo' verfügbar sind. – MarcinJuraszek

Verwandte Themen