Laden...

dynamic bzw. ExpandoObject: dynamische Properties per GetProperties auslesen

Erstellt von Quaneu vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.682 Views
Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 12 Jahren
dynamic bzw. ExpandoObject: dynamische Properties per GetProperties auslesen

Hallo,

ich hätte folgende Frage:

Ich würde gern mit dynamic bzw. ExpandoObject dynamisch ein "Objekt" erzeugen.
Eigentlich würde ich nur gern dynamisch Properties erzeugen. Um sie später bei Bedarf über Reflection "auszulesen".

Beispiel:


dynamic person = new ExpandoObject();
// es sollen Properties hinzugefügt werden und danach sollen diese wie folgt //ausgelsen werden
PropertyInfo[] infos = person.GetType().GetProperties();

Wenn ich dies jedoch versuche, bekomme ich immer keine Properties. Daher meine Frage, ist dieser Weg möglich, bzw. gibt es überhaupt einen Weg, dies zu realisieren?

Viele Grüße
Quaneu

C
1.214 Beiträge seit 2006
vor 12 Jahren

Was zu realisieren? Was genau willst du denn erreichen, warum brauchst du PropertyInfo Objekte? Mit dynamic könntest du ja folgende Syntax erreichen:

string value = dynamic.MyValue;

Also, einfach auf die Eigenschaft zugreifen, ohne dass der Compiler sie kennt. Intern könntest du sie z.B. in einem Dictionary verwalten.
Du könntest aber auch die Schnittstelle ICustomTypeDescriptor implementieren, damit hättest du auch dynamische Eigenschaften, nur nicht so elegant und transparent.

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 12 Jahren

Also ich habe ein Programm, dem ich eine Instanz einer Klasse übergebe und das Programm analysiert die Properties dieser Klasse über Reflection (GetProperties() usw.) und erzeugt mir dann eine XML-Datei.

Nun würde ich dieses Programm gerne erweitern, indem ich z.B. Excel Dateien lese und mir dann dynamisch eine Klasse baue, die ich dann meinem Programm übergeben kann.

C
1.214 Beiträge seit 2006
vor 12 Jahren

Wenn das Programm nur Reflection nutzt, wird es glaub ich nicht gehen. Hast du Zugriff darauf, kannst du es erweitern? Dann könntest du wie gesagt ICustomTypeDescriptor nutzen. Das könnte in etwa so ausschauen:


void method(object parameter)
{
  ICustomTypeDescriptor td = parameter as ICustomTypeDescriptor;
  if (td != null)
  {
    var properties = td.GetProperties();
    ...
  }
  else
  {
     //use reflection
  }
}

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 12 Jahren

Ich habe schon zugriff auf das Programm, wollte es aber eigentlich nicht mehr ändern.

Aber wenn es keine andere Möglichkeit, muss ich wohl doch Änderungen an diesem vornehmen.

Vielen Dank schon mal für Deine Hilfe.

Grüße
Quaneu

C
1.214 Beiträge seit 2006
vor 12 Jahren

So wie ich das sehe, gibt es keine Möglichkeit. Das würde auch das Konzept brechen. Reflection ist eben Reflection und soll Zugriff auf den eigentlichen Typen bieten. Wenn du z.B. von DynamicObject ableitest, und "dynamisch" Properties zur Verfügung stellst, bietet das Laufzeitsystem eben einen Mechanismus, auf diese Eigenschaften zuzugreifen. Diesen Mechanismus nutzt du auch, wenn du das dynamic Schlüsselwort verwendest. Wenn du nun auf dem Objekt GetType aufrufst, ist der Typ DynamicObject und DynamicObject hat diese dynamischen Eigenschaften natürlich nicht.

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 12 Jahren

Und eine andere Möglichkeit Properties dynamisch hinzufügen, so dass man sie mit GetType().GetProperties() gibt es nicht?

Dann werde ich deinen Vorschlag in die Tat umsetzten.

Nochmals vielen Dank.

C
1.214 Beiträge seit 2006
vor 12 Jahren

Wie gesagt, das würde alles das Prinzip von Reflection untergraben. Die einzige Möglichkeit, die mir einfällt, ist wirklich einen neuen Typ dynamisch zur Laufzeit zu erstellen, z.B. mit Reflection Emit oder Mono Cecil. Aber das ist ein ziemlicher Overkill.

I
279 Beiträge seit 2008
vor 12 Jahren

Hi,

mit

myExpandoObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)

kommst du an die Eigenschaften des ExpandoObjects.

Innerhalb der Eigenschaften "Keys" und "Values" befinden sich Informationen zu deinen hinzugefügten Eigenschaften.

In "Keys" demnach der Membername und in "Values" deren Werte.

Auf die Schnelle konnte ich aber nicht feststellen ob sich irgendwo noch Typinformationen zu den Eigenschaften befinden.

Mittels

MethodInfo tryAddMemberMethod = myExpandoObject.GetType().GetMethod("TryAddMember", BindingFlags.Instance | BindingFlags.Public |BindingFlags.NonPublic);

            tryAddMemberMethod.Invoke(z, new object[]
                                {
                                    "NeuerTest", 334
                                });


            var neuerTest = z.NeuerTest;

Kannst du sogar dynamisch zur Laufzeit dynamische Member zu einem dynamischen Typen (ExpandoObject) hinzufügen.

Wie gesagt, das würde alles das Prinzip von Reflection untergraben

Wieso sollte das System von Reflektion untergraben werden Wenn man dynamisch erzeugte Typen mit dieser reflektieren kann? Das ergibt keinen Sinn, es würde eher Sinn ergeben zu sagen das das System von Reflektion untergraben wird wenn es Typen im Typsystem gibt die nicht mit Reflektion untersucht werden können!

C
1.214 Beiträge seit 2006
vor 12 Jahren

Wieso sollte das System von Reflektion untergraben werden Wenn man dynamisch erzeugte Typen mit dieser reflektieren kann? Das ergibt keinen Sinn, es würde eher Sinn ergeben zu sagen das das System von Reflektion untergraben wird wenn es Typen im Typsystem gibt die nicht mit Reflektion untersucht werden können!

Ok, das ist wohl Ansichtssache. Für mich ist C# keine dynamische Sprache, deswegen will ich mit Reflection auf den eigentlichen Typen, in dem Fall ExpandoObject zugreifen, und der Typ ist ja schon zur Kompilierzeit "fertig". Wenn ich mit Reflection auf die dynamischen hnzugefügten Member zugreife, ist es eine Erweiterung des Reflection Konzepts. Ich finde, dass es damit ausgetrickst wird... Aber anscheinend bist du anderer Meinung, also wohl Ansichtssache...