Laden...

Reflection und konkrete Objekte zur Laufzeit

Erstellt von the_lmich vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.340 Views
the_lmich Themenstarter:in
248 Beiträge seit 2005
vor 16 Jahren
Reflection und konkrete Objekte zur Laufzeit

Tach zusammen,

jetzt schlage ich mich schon länger durch die Themen Reflection und Late-Binding und komme zu einem Schluss, den ich durch Euch noch festigen möchte.

Ich kann im .NET Framework 2.0 zur Laufzeit via Reflection den Typen eines Objekts, seine Member, etc. herausbekommen - auch wenn das Objekt in einem anderen enthalten ist. (Im Extremfall in "object")
Ich habe weiterhin die Möglichkeit mit Hilfe dieser Information irgendein konkretes Objekt dieses Typen zu instanziieren.

Ich komme aber nicht an **das **konkrete Objekt, **diese **eine Instanz, die bspw. in "object" steckt. Oder habe ich da was übersehen? (Und zwar immer angenommen ich kenne den Typen nicht!)

Zur Verdeutlichung:


Class1 concreteObject = new Class1();
concreteObject.name = "123";
object o = concreteObject;

Komme ich jetzt auch nur irgendwie an das Objekt mit dem Namen "123", wenn ich nur o habe? Ich denke nicht, oder? Ich müsste in den bekannten Typ casten und das geht ja nur zur Compiletime.

Für neuere oder bessere Erkenntnisse wäre ich sehr dankbar.

Viele Grüße
🙂 Torsten

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo the_lmich,

klar kommst du an name ran. Je nachdem ob name Property oder Field ist, verwendest du PropertyInfo/FieldInfo.GetValue.

herbivore

P
18 Beiträge seit 2007
vor 16 Jahren

moin,

habe mich noch nicht wirklich mit der Reflections-API beschäftigt, aber kannst du nicht sowas wie getMethods() machen ? dann schaust du nach getName() und prüfst ob == "123"...

ist zwar nicht genau das was du suchst aber ein Anfang wärs ja mal

grtz,
plusminus

830 Beiträge seit 2005
vor 16 Jahren

Hallo the_lmich,

besser so wie herbivore sagt:


PropertyInfo pInfo = o.GetType().GetProperty("name"); //name ist Property in Class1
FieldInfo fInfo = o.GetType().GetField("name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) // name ist private, oder public Field in Class1

Den Wert bekommst du für die Propery-Variante bspw. so:


object value = pInfo.GetValue(o, new object[]{ });

Gruss
Friedel

Ohne Ziel ist auch der Weg egal.

3.971 Beiträge seit 2006
vor 16 Jahren

Also Casten direkt geht zur Ausführung nicht. Möglich wäre aber


switch (o.GetType().FullName)
{
  case "Class1":
    ...
  break;
  case "Class2":
    ...
  break;
}

oder dann bei abgeleitetenden Klassen oder Interfaces


if (o.GetType().IsSubClassOf(typeof(BaseClass)))
{
   ...
}

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo kleines_eichhoernchen,

casten geht nicht, ist aber auch nicht nötig, da der Zugriff auf die Property einfach per Reflection erfolgen kann.

Aber zu deinen Konstrukten:

Den erst Vorschlag finde ich ganz grausam. Sowas ist nie nötig.

Und statt des zweiten sollte man besser und einfacher if (o is BaseClass) verwenden.

herbivore

the_lmich Themenstarter:in
248 Beiträge seit 2005
vor 16 Jahren

Okay, ich sehe schon. Casten geht nicht - wie ich dachte. Ich komme aber an alle Werte des konkreten Objekts. Und wenn es wieder Referenztypen sind, bekomme ich den vollen Pfad zurück. Damit kann ich mich dann weiterhangeln.

Wieder was gelernt. Danke Euch!

Grüße
🙂 Torsten

the_lmich Themenstarter:in
248 Beiträge seit 2005
vor 16 Jahren

Sorry, einen hab' ich noch:

Falls mein Wert / Objekt von Type.IsClass ist komme ich an das nächste Objekt. Ist es vom Type.IsArray caste ich in ein object[] und kann iterieren, komme so an meine Werte / Objekte
Was aber wenn mein Value von Typ List<T> ist? Zunächst mal prüfe ich mit:


if (srcType.IsClass && (srcType.Namespace == "System.Collections.Generic" || srcType.Namespace == "System.Collections"))

was ich grundsätzlich unsauber finde. Aber ich finde kein Type.IsCollection o.ä. und auf realisierte Interfaces wie IEnumerable<T> kann ich nicht prüfen.

Whatever, mein Problem ist aber folgendes: Ich bekomme ein object rein, in dem eine List<T> steckt. Und finde gearde keine Möglichkeit darüber zu iterieren, da ich ja zur Compilezeit nur object habe und nicht so schön casten kann wie bei Array.

Irgendeiner 'ne Idee?

Danke vielmals im voraus
🙂 Torsten

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo the_lmich,

und auf realisierte Interfaces wie IEnumerable<T> kann ich nicht prüfen.

Warum nicht? Das wäre genau das richtige.

Es reicht ja aber zu fragen: if (o is IEnumerable) bzw. mit as auf IEnumerable zu casten und dann foreach zu benutzen. So geht es auf jeden Fall!

herbivore

the_lmich Themenstarter:in
248 Beiträge seit 2005
vor 16 Jahren

Mist, entweder ist es ist noch zu früh oder schon wieder zu spät 🙂 Klappt natürlich!
Darf man nur nicht den Typ auf IEnumerable prüfen, sondern das Objekt ...

Danke ... das hätte mich wohl um meine Pizza gebracht 😁

🙂 Torsten