Benutzer mit den meisten Antworten
Struktur durchgehen

Frage
-
Hallo,
kann man die Elemente einer Struktur "durchgehen"??
So etwa
public struct BspStruktur { public string strElement1; public string strElement2; public string strElement3;}
...BspStruktur bspStruktur = new BspStruktur();
foreach (string zBezeichnung in bspStruktur)
{
MessageBox.Show("Struktur-Element: " + zBezeichnung);
}
Antworten
-
Hallo p
nicht mit C# alleine, aber zB Reflection, Pseudo-Code grob:
using System.Reflection;
// ...
foreach (FieldInfo field in typeof(BspStruktur).GetFields())
MessageBox.Show("Struktur-Element: " + field.Name + "=" + field.GetValue(bspStruktur));
MSDN
http://msdn.microsoft.com/de-de/library/ch9714z3.aspx
http://msdn.microsoft.com/de-de/library/system.reflection.fieldinfo.getvalue.aspx- Als Antwort markiert perlfred Dienstag, 14. Dezember 2010 16:29
- Bearbeitet Thomas Scheidegger Dev Dienstag, 14. Dezember 2010 16:50
Alle Antworten
-
Hallo p
nicht mit C# alleine, aber zB Reflection, Pseudo-Code grob:
using System.Reflection;
// ...
foreach (FieldInfo field in typeof(BspStruktur).GetFields())
MessageBox.Show("Struktur-Element: " + field.Name + "=" + field.GetValue(bspStruktur));
MSDN
http://msdn.microsoft.com/de-de/library/ch9714z3.aspx
http://msdn.microsoft.com/de-de/library/system.reflection.fieldinfo.getvalue.aspx- Als Antwort markiert perlfred Dienstag, 14. Dezember 2010 16:29
- Bearbeitet Thomas Scheidegger Dev Dienstag, 14. Dezember 2010 16:50
-
Hallo perlfred,
Hier noch eine LINQ-Iteration als Inspirationsquelle:
using System; using System.Linq; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var query = from m in typeof(Person).GetFields() // auch GetMembers moegl. mit entspr. BindingFlags select m; foreach(var m in query) Console.WriteLine(m.Name); Console.ReadKey(true); } } struct Person { public string FirstName; public string LastName; } }
Gruß
Marcel -
Hallo,
und LINQ mit Ausgabe der Werte:
public struct BspStruktur { public string Element1; public string Element2; public string Element3; public static void DisplayFieldValues() { var beispiel = new BspStruktur() { Element1 = "abc", Element2 = "def", Element3 = null }; var values = from field in beispiel.GetType().GetFields() // Oder auch KeyValuePair<K, V> select new Tuple<string, object>(field.Name, field.GetValue(beispiel)); foreach (var value in values) Console.WriteLine("{0} = {1}", value.Item1, value.Item2); }
um das Thema abzurunden ;-)
Gruß Elmar
-
Hallo Elmar,
> um das Thema abzurunden ;-)
ein Thema kann man ja im ~Prinzip nie abrunden, weil es immer noch andere Möglichkeiten gibt ;-)
Gut, Dein Beispiel benutzt ja das GetFields, was Thomas richtigerweise vorgeschlagen hatte. Aber Reflection (hier GetFields) ist ja oft vermeidbar, und sollte vermieden werden (wenns es etwas anders gibt), u.a., weil es imperformant ist. Gut wenn ihr einen Cache eingebaut hättet (insgesamt wird es dann ggf. nur einmal evaluiert), wäre es ggf. noch performanter, aber immer noch nicht wie in folgendem Beispiel. Man kann also zum Beispiel auch (ganz simpel) folgendes machen, mit dem Aufruf:foreach (var feld in BspStruktur.Felder) // hier sehr performant MessageBox.Show(feld);
// ......................
public struct BspStruktur { public string Element1; public string Element2; public string Element3; // diese Ziele ggf. über PreBuild automatisch erstellen lassen static public string[] Felder = new string[] { "Element1", "Element2", "Element3" }; }
Man kann da auch viel weiter gehen (oder sogar den struct partial machen) und letztlich über T4 Vorlagen (oder T4 MsBuild Integration - als PreBuild-Step) noch verhindern, dass beim Zufügen eines Element4's die "Felder" Liste auch angepasst wird, es gibt sehr viele Möglichkeiten. So wird die Performanz auf Kompilieren verschoben und nicht während der Ausführung langsamer.
Auch wäre das eine ideale Aufgabe für PostSharp:
[PostSharp – Documentation]
http://www.sharpcrafters.com/postsharp/documentation
ciao Frank- Als Antwort vorgeschlagen Marcel RomaModerator Mittwoch, 15. Dezember 2010 08:20
-
Hallo Frank,
Die Markierung als Antwort war ein Ausrutscher, sorry (wiewohl Du in dem einen oder anderen Punkte Recht hast).
> Aber Reflection (hier GetFields) ist ja oft vermeidbar, und sollte vermieden werden (wenns es etwas anders gibt), u.a., weil es imperformant ist.
Reflection wurde - wie Du sicherlich weißt - auf dem Hintergrund von late-binding Szenarios entworfen. Von daher steckt sehr viel Kraft dahinter, die ihrerseits natürlich Performanz konsumiert. Und vieles kann auch hier über Caching wieder gut gemacht werden. Es gibt aber auch andere Wege an die benötigte Metadaten-Information zu kommen: z.B. Mono.Cecil (eine ausgezeichnete Bibliothek, wird z.B. intern von NDepend verwendet). Und wer ganz low-level arbeiten möchte, der kann sich natürlich das Common Compiler Infrastructure von Microsoft Research auf CodePlex ansehen. Ein Wort der Warnung jedoch: Microsoft.CCI ist nichts für Leute mit schwachen Nerven.
Gruß
Marcel -
Hallo Marcel,
ja, es gibt immer noch andere Möglichkeiten etwas umzusetzen, meine präferierten Tools sind momentan in diesem Bereich eher die in meinem ersten Posting angegebenen - trotzdem ist da kein Anspruch auf Vollständigkeit vorhanden, es gibt viele weitere gute, die noch nicht genannt wurden.
ciao Frank