Laden...

Reflection-Problem mit Interfaces

Erstellt von typhos vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.786 Views
T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren
Reflection-Problem mit Interfaces

Hallo!
Ich habe (mal wieder) ein Problem mit Reflection. Und zwar versuche ich, mithilfe von Reflection (PropertyInfo) die Eigenschaften und deren Werte von Objekten auszulesen. Das ist eigentlich auch kein Problem und funktioniert prima.

Nur habe ich jetzt folgende Situation:
Es handelt sich um eine Client-/Server-Anwendung.
Ich habe mehrere Klassen erstellt, die von MarshalByRefObject erben und jeweils ein eigenes Interface implementieren. Die Klassen liegen am Server, der Client kennt nur die Interfaces.
So, wenn ich am Server Objekte (der dort vorhandenen Klassen) erzeuge und deren Eigenschaften auslese, funktioniert das gut. Wenn ich allerdings Objekte der auf dem Server liegenden Klassen am Client erstelle (dort sind sie ja dann vom Typ des zugehörigen Interfaces), bekomme ich bei der Typabfrage nur den Typ MarshalByRefObject. MarshalByRefObject kennt natürlich keine Eigenschaften und daher kann ich sie nicht auslesen.

Hier nochmal zur Verdeutlichung:

Auf dem Server:

public class MeinTyp() : MarshalByRefObject, IMeinTyp
{
}

MeinTyp myObj = new MeinTyp();
PropertyInfo[] test = myObj.GetType().GetProperties();

Das läuft prima und das PropertyInfo-Array test ist auch gefüllt.

Am Client:


IMeinTyp myObj = ErzeugeInstanzDesRemoteObjekts();
PropertyInfo[] test = myObj.GetType().GetProperties();

Hier ist test nicht gefüllt, weil GetType() eben nicht (wie von mir erwartet) IMeinTyp liefert, sondern den Basistyp MarshalByRefObject. Damit werden natürlich meine Properties nicht gefunden.

Hat jemand eine Idee, wie ich an die Eigenschaften sowie deren Werte des Remote-Objekts gelange?
Wenn ich ganz normal mit myObj.MeineEigenschaft darauf zugreife, funktioniert das selbstverständlich, nur halt nicht mit Reflection.

Würde mich wirklich freuen, wenn mir hier jemand helfen könnte.

L
254 Beiträge seit 2005
vor 17 Jahren

Hmm hoffer erzähle dir keinen mist.

Probier mal


IMeinTyp mT = test as IMeinTyp;

Wenn du da null bekommst, dann wäre es nicht vom Typ gewesen in den du es "gesoft-castet" hast.

In deinem Fall müsste das aber fast sicher gehen.

Gruss

If you can't make it, fake it.

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Danke für den Tipp. Aber leider bringt mT.GetType().Name immer noch MarshalByRefObject.
IntelliSense zeigt mir ja auch an, dass mein Objekt vom Typ IMeinTyp ist, aber GetType().Name bringt immer den Basistyp MarshalByRefObject.

Ich find' das echt nicht mehr schön 🙁

6.862 Beiträge seit 2003
vor 17 Jahren

GetType liefert wohl immer ne Klasse enn auch ne Klasse vorhanden ist, aber IMO könntest du ja versuchen mit GetInterfaces die Interfaces die implementiert sind abzurufen und die dann zu prüfen.

Baka wa shinanakya naoranai.

Mein XING Profil.

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Hallo talla,
das habe ich auch schon probiert, aber mT.GetType().GetInterfaces() gibt ein leeres Array zurück.
Mir scheint, als würde ich dabei auch wieder nur die Interface-Liste von MarshalByRefObject zurück bekommen... 😭

L
254 Beiträge seit 2005
vor 17 Jahren

Hmm sorry, hab was falsch verstanden/gelesen mein Tip von vorhin hat nicht wirklich mehr gemacht als du sowieso schon machst;

Mit typeof(IMeinTyp).GetProperties();

Kriegst du deine Props.

If you can't make it, fake it.

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Ja, das funktioniert schon. Aber das hilft mir nicht sehr weiter, da ich bei dem folgenden Aufruf eine NullReferenceException bekomme. Also findet er die Property wohl nicht im Objekt. Sie ist aber mit Sicherheit drin, aber ich werde mir wohl eine andere Lösung einfallen lassen müssen...

typeof(IMeinTyp).GetProperty("Eigenschaft").GetValue(mT, null)

Ich kann hiermit also auf die Eigenschaften zugreifen, aber nicht auf deren Werte, die im Objekt mT sind 🙁

edit: nur zur Info: Wenn ich zum Test die BL-Assembly im Client einbinde, in der auch die Klasse MeinTyp implementiert ist und mT auf MeinTyp caste funktioniert es problemlos. Nur mit den Interfaces geht es nicht, aber der client soll die Implementierung ja nicht kennen...

L
254 Beiträge seit 2005
vor 17 Jahren

Hmm

vielleicht mach ich auch was falsch kann dir aber nicht helfen(soweit ich sehe machst du alles richtig)

das hier funzt;


IList iList = new ArrayList();
iList.Add("item");
bool isReadOnly = (bool)typeof(IList).GetProperty("IsReadOnly").GetValue(iList,null);

Natürlich muss die Eigenschaft die du brauchst im Interface definiert sein, und nicht im Objekt das dieses Interface implementiert?

Wie du gesagt hast sollst du die Implementation nicht kennen (also auch nicht das Property auf der Implementation 😉)

If you can't make it, fake it.

4.221 Beiträge seit 2005
vor 17 Jahren

Kannst Du die Werte nicht mit SerializationInfo.GetValue ziehen ? (den Namen und Type der einzelnen Properties kannst Du ja über Reflection aus dem Interface ziehen).

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

T
512 Beiträge seit 2006
vor 17 Jahren

Das Problem ist, dass dein Client die echte Klasse nicht kennt, und GetType() da logischerweise nichts sinnvolles liefern kann. Woher soll er denn die Typinformationen für Reflection nehmen?

Es wäre sowieso logischer wenn die Informationen die der Client braucht alle über das Interface geholt werden können. Also du fügst dem Interface z.B. eine Funktion GetProperties() hinzu. In der Implementation des Interfaces solltest du problemlos this.GetType().GetProperties() verwenden können.

e.f.q.

Aus Falschem folgt Beliebiges

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 17 Jahren

Original von Traumzauberbaum
Das Problem ist, dass dein Client die echte Klasse nicht kennt, und GetType() da logischerweise nichts sinnvolles liefern kann. Woher soll er denn die Typinformationen für Reflection nehmen?

Eben! Genau as ist ja das Problem. Ich dachte, er nimmt die Typinformationen auch vom Interface...

Aber OK, ich mache es nun mit der von Dir vorgeschlagenen Methode: Ich habe im Interface (und der zugehörigen Klasse) nun eine Methode GetProperties() eingefügt, die mittels this.GetType()... die Infos holt.

Danke dafür!

@ Programmierhans: Mit SerializationInfo kenne ich mich (noch) nicht aus. Dazu brauche ich ja noch einen Formatconverter - keine Ahnung, wie das läuft.