2012-06-22 1 views
9

Betrachten Sie die folgende Klasse erhalten:Wie kann ich Reflection verwenden Sie den Wert eines statische Eigenschaft eines Typ ohne eine konkrete Instanz

public class AClass : ISomeInterface 
{ 
    public static int AProperty 
    { 
    get { return 100; } 
    } 
} 

ich eine andere Klasse dann wie folgt:

public class AnotherClass<T> 
    where T : ISomeInterface 
{ 

} 

was ich zB über:

AnotherClass<AClass> genericClass = new AnotherClass<AClass>(); 

Wie kann ich den statischen Wert von AClass.AProperty aus meinem Generic bekommen ohne eine konkrete Instanz von AClass zu haben?

Antwort

10

So etwas wie

typeof(AClass).GetProperty("AProperty").GetValue(null, null) 

tun wird. Vergiss nicht zu int zu werfen.

Link zur Dokumentation: http://msdn.microsoft.com/en-us/library/b05d59ty.aspx (sie haben auch Beispiel mit statischen Eigenschaften.) Aber wenn Sie genau wissen AClass, können Sie nur AClass.AProperty verwenden.

Wenn Sie innerhalb AnotherClass<T> für T = AClass, Sie es als T verweisen:

typeof(T).GetProperty("AProperty").GetValue(null, null) 

Das funktioniert, wenn Sie sicher sind, dass Ihre TAProperty statische Eigenschaft hat. Wenn es keine Garantie dafür gibt, dass eine solche Eigenschaft auf einer T existiert, müssen Sie die Rückgabewerte/Ausnahmen auf dem Weg überprüfen.

Wenn nur AClass interessant für Sie ist, können Sie so etwas wie

if (typeof(T) == typeof(AClass)) 
    n = AClass.AProperty; 
else 
    ??? 
+0

Großen. Das einzige Problem, das ich jetzt entdeckt habe, ist, dass ich die statische Eigenschaft in der Schnittstelle nicht definieren kann, die es tun muss. Ich denke, ich könnte eine nicht statische Eigenschaft und eine statische Eigenschaft hinzufügen, die denselben Wert zurückgibt, einen für die zu verwendende Instanz und einen für den Typ, auf den verwiesen wird. Oder gibt es einen anderen Weg? –

+0

Alternativ könnte ich die nicht statische Eigenschaft mit neuen T(). AProperty, aber das scheint wie es wäre schlechte Praxis. Was denken Sie? –

+0

@Stewart: Nun, die Konstruktion eines neuen 'T' könnte teuer sein. Es ist schade, dass Interfaces statische Dinge nicht beinhalten können. – Vlad

1

verwenden zunächst die generische Typ Ihres AnotherClass Instanz erhalten.

Dann erhalten Sie die statische Eigenschaft.

Dann erhalten Sie den statischen Wert der Eigenschaft.

// I made this sealed to ensure that `this.GetType()` will always be a generic 
// type of `AnotherClass<>`. 
public sealed class AnotherClass<T> 
{ 
    public AnotherClass(){ 
     var aPropertyValue = ((PropertyInfo) 
       this.GetType() 
        .GetGenericArguments()[0] 
        .GetMember("AProperty")[0]) 
      .GetValue(null, null); 
    } 
} 

erkennen, natürlich, dass es nicht möglich ist, um sicherzustellen, dass „AProperty“ existiert, weil Schnittstellen funktionieren nicht auf statische Signaturen, entfernte ich ISomeInterface in Bezug auf die Lösung irrelevant zu sein.

Verwandte Themen