Entwickler-Ecke
Basistechnologien - Problem mit Reflection /SetValue
frenchcancan - Mi 11.05.11 13:26
Titel: Problem mit Reflection /SetValue
Hallo!
ich habe ein dynamisches Objekt. Die Namen der Felder kenn ich erst zur Laufzeit.
Das Anlegen der Felder und deren Wert Zuweiseung geht, wenn ich es direkt mache, aber nicht mehr, wenn ich über die Methode SetValue arbeiten will.
C#-Quelltext
1: 2: 3: 4:
| using System.Dynamic; using System.Reflection; using System.Text.RegularExpressions; using MBLib.SystemTools.Dynamic; |
....
zum Beispiel
dynamic obj = new Person();
obj.NachName = "Mueller";
obj.Vorname = "Anton";
obj.Alter = 23;
// das funktioniert bis hierher
Da ich aber noch nicht die Feldname kenne, möchte ich gern über die Refelction arbeiten. Und da scheine ich etwas Grundsätzliches nicht zu verstehen:
ich würde es so machen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| string neuesFeld = "AnzahlKinder"; int value = 2;
Type t = typeof(Person); FieldInfo myFieldInfo = t.GetField(neuesFeld , BindingFlags.NonPublic | BindingFlags.Instance); myFieldInfo.SetValue(obj,value); |
und da verstehe ich nicht, warum ich als parameter ein Objekt geben soll und keinen Wert eingeben darf.
wie weise ich den Wert 2 zum Feld AnzahlKinder zu? Warum erwartet diese Methode SetValue ein Objekt?
Ich wäre dankbar, wenn jemand mir ein Beispiel geben könnte, wie ich es realisieren soll,
Vielen Dank im Voraus
frenchcancan
Moderiert von
Kha: Topic aus WinForms verschoben am Mi 11.05.2011 um 17:53
Trashkid2000 - Mi 11.05.11 13:58
Hallo,
ich verstehe nicht so richtig, warum Du auf Reflection zurückgreifst. Die Propertys kannst Du doch auch so abfragen, und ganz normal setzen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| dynamic aPerson = new ExpandoObject(); aPerson.Name = "Mario Meir-Huber"; aPerson.Age = 25;
foreach (var property in (IDictionary<string, object>)aPerson) { } |
Aber ich persönlich finde dynamics auch irgendwie naja.
LG, Marko
Ralf Jansen - Mi 11.05.11 14:01
Zitat: |
Die Namen der Felder kenn ich erst zur Laufzeit. |
Eigentlich solltest du die Namen privater Felder nie kennen. Dafür sind die ja privat. Das was du da tust würde ich als Hack bezeichnen.
Zitat: |
und da verstehe ich nicht, warum ich als parameter ein Objekt geben soll und keinen Wert eingeben darf. |
Natürlich darfst du das. Alles ist letztlich ein Object also sollte auch Integer problemlos gehen. In diesem Fall unter der Annahme das du auch ein privates nicht statisches Feld hast das 'AnzahlKinder' heißt. Allein vom Naming her finde ich das verdächtig >99% aller Entwickler würden private Feldvariablen klein schreiben. Bist du dir sicher das AnzahlKinder nicht eher eine Property ist und kein Feld und nebenbei das die public ist und nicht private?
Edit : Beim schreiben dieser Antwort habe ich nicht berücksichtigt (weil übersehen) das dynamic verwendet wird.
Yogu - Mi 11.05.11 14:55
Spricht eigentlich etwas gegen ein Dictionary<string, object>?
frenchcancan - Mi 11.05.11 15:19
Zitat: |
Bist du dir sicher das AnzahlKinder nicht eher eine Property ist und kein Feld und nebenbei das die public ist und nicht private?
|
in
Vielleicht leigen die problem tatsächlich daran, dass das Objekt dynamisch ist.
Wenn ich folgendes schreibe:
C#-Quelltext
1: 2: 3:
| dynamic obj = new simpleObject(); obj.Name = "Mueller"; obj.Vorname = "Anton"; |
erzeuge ich 2 neue Properties denke ich und weise ihnen den Wert "Mueller", bzw. "Anton" zu.
Komplizierter ist es, weil das Object dynamisch ist und aus einer Textdatei heraus gebildet wird , deswegen weiss ich nicht wie die Propertynamen sind, also z. "AnzahlKinder", den ich auf "2" setzen will
Wie würde ich das denn machen?
Könnt ihr mir ein Beispiel geben?
Danke im Voraus
Kha - Mi 11.05.11 15:39
Ich schließe mich Yogu an: Wenn immer nur dynamisch per String zugegriffen wird, wozu dann überhaupt Properties?
Ralf Jansen - Mi 11.05.11 20:09
Zitat: |
erzeuge ich 2 neue Properties denke ich und weise ihnen den Wert "Mueller", bzw. "Anton" zu. |
Nein. Du erzeugst Code der so aussieht als hättest du 2 Properties erzeugt. Ist aber reine Compilermagie. Letztlich ist dieser Dynamic Datentyp den du da an der Hand hast nur ein Dictionary und der Compiler täuscht dir vor es wären Properties. Reflection läuft da also ins leere. Solltest dir den Code vielleicht einfach mal im Reflector ansehen da wird es offensichtlich das das nicht funktionieren kann. Am besten die hier eh nicht hilfreiche Compilerilussion weglassen und, wie hier mehrfach empfohlen, gleich ein echtes Dictionary nehmen.
frenchcancan - Do 12.05.11 11:12
Ja, also offensichtlich gehe ich das falsch an.
Wie würdet ihr das machen, wenn ihr eine Textdatei hättet, in der zum Beispiel "Name;Mueller;" oder "Vorname;Anton;" oder "Alter;24;" steht, um daraus automatisch ein Objekt zu erstellen in der die Werte zugewiesen sind.
Gibt es nicht ein kleines Beispiel, damit ich weiß, wie ich anfangen soll?
Vielen Dank im Voraus
frenchcancan
Ralf Jansen - Do 12.05.11 12:30
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Dictionary<string, string> person = new Dictionary<string, string>();
foreach (var line in File.ReadAllLines("MeinLiebenDaten.csv")) { string[] keyValuePair = line.Split(new char[] {';'}, 2, StringSplitOptions.RemoveEmptyEntries); if (keyValuePair.Length != 2) throw new Exception("Bäng"); person[keyValuePair[0]] = keyValuePair[1]; }
if (person.ContainsKey("Name")) Console.WriteLine("Name = " + person["Name"]); |
Beispiel mit der Annahme das deine Datei je Zeile 2 durch ein Semikolon separierte Strings enthält. Also etwa
Quelltext
1: 2: 3:
| Name;Mueller Vorname;Anton Alter;24 |
frenchcancan - Do 12.05.11 14:03
Vielen Dank!
ich kann es leider erst montag probieren aber es hilft mir weiter
frenchcancan
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!