Geschrieben von: Alexander Zeitler
Kategorie: .NET Fu
This printed page brought to you by AlphaSierraPapa
Will man zum Beispiel einem selbst entwickelten User- oder Server Control eine DataSource Property spendieren, welche außer DataSets und Collections auch selbst (oder von Dritten) entwickelte Objekte (Klassen) verarbeiten kann, ist es notwendig, dass diese von einer von uns bereitgestellten Klasse erben oder ein Interface (z.B. ICollection) implementieren - im Normalfall.
Doch was tun, wenn der Entwickler, der unser Control verwendet, völlig frei in der Gestaltung seiner Klassen sein soll, die er als DataSource zuweisen möchte? Ein Beispiel aus der Praxis: Wir entwickeln ein User Control, das Daten ähnlich dem DataGrid präsentiert. Der Entwickler hat nun eine Klasse Product, deren Properties er gerne mit unserem Control darstellen möchte. Da der Entwickler das Design seiner Product-Klasse selbst festlegen muß (wir wissen nicht, welche Eigenschaften seine Produkte besitzen), können wir ihm auch kein Interface bereitstellen, das er implementieren kann.
Die Lösung heißt Reflection. Das sogenannte Reflection API befindet sich im .NET Framework in dem Namespace System.Reflection und liest aus den Metadaten der Objekte die Informationen über die angesprochenen Objekte bzw. deren Typen aus, d.h. die Objekte reflektieren über sich selbst.
Die Metadaten beinhalten Informationen über Methoden, Eigenschaften, Events usw. der Objekttypen:
Wie kommen wir nun an diese Informationen? Wie bereits erwähnt, gewinnt Reflection die Informationen aus den Typen (bzw. deren Metadaten) selbst, d.h. wir müssen den Typ einer Instanz eines Objektes feststellen, über das wir Informationen erhalten möchten.
In unserem Fall müssen wir die DataSource-Eigenschaft - genauer die Items in dieser DataSource - zur Typbestimmung heranziehen. Die Typbestimmung geschieht über die Methode .GetType(), welche jedes Objekt bereitstellt:
foreach(object DataSourceItem in DataSource) { Type t = DataSourceItem.GetType(); }
Um nun alle Eigenschaften (Properties) eines Typs zu lesen, verwenden wir die Methode GetProperties(). Diese liefert ein Array vom Typ PropertyInfo zurück, welches die Properties beinhaltet. Das Auslesen aller Properties funktioniert wie folgt:
foreach(System.Reflection.PropertyInfo pi in t.GetProperties()) { Response.Write("Name der Eigenschaft: "); Response.Write(pi.Name + "<br>"); Response.Write("Typ der Eigenschaft: "); Response.Write(pi.PropertyType + "<br><br>"); }
Analog hierzu gibt es z.B. für Methoden die Klasse MethodInfo - für Events verwenden wir EventInfo.
Außerdem ist es auch möglich, gezielt auf Eigenschaften usw. zuzugreifen. Hierzu gibt es z.B. die Methode .GetProperty (also Singular statt Plural im Methodenname).
Doch nicht nur die Eigenschaften, Methoden usw. von Objekten lassen sich per Reflection auslesen, sondern auch deren Inhalte.
Der Wert einer Eigenschaft eines instanzierten Objekts lässt sich mit der GetValue()-Methode herausfinden:
Response.Write("Wert der Eigenschaft:"); Response.Write(pi.GetValue(DataSourceItem,null).ToString() + "<br>");
Doch selbst hier ist Reflection noch nicht am Ende - Reflection erlaubt auch das Aufrufen von Methoden eines Objekts zur Laufzeit - ermöglicht wird das durch die Invoke-Methode der MethodInfo-Klasse - hier am Beispiel einer Product-Klasse, deren Delete-Methode wir zur Laufzeit ausführen werden:
Product myProduct = new Product(); Type t = myProduct.GetType(); MethodInfo mi = t.GetMethod("Delete"); mi.Invoke(p, null);
Wie man sieht, ist Reflection nicht nur graue Theorie, sondern auch in der Praxis durchaus nützlich und notwendig. Ein weiteres Beispiel aus der Praxis, das nahezu jeder täglich beim Entwickeln nutzt, ist die in Visual Studio .NET integrierte IntelliSense.
Weitere Informationen zum Reflection API finden sich in der Dokumentation des System.Reflection-Namespaces.
This printed page brought to you by AlphaSierraPapa
Dokumentation des System.Reflection-Namespaces
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemreflection.asp
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.