Im Zuge eines Projektes musste eine komplexe ineinander verschachtelte Klassenstrukturen aufgebaut werden, um eine ebenfalls komplexe Interfacestruktur einer externen Anwendung abzubilden.
Um bei Fehlermeldungen und beim Debuggen (ja ich oute mich, ich debugge auch Code) ordentliche Daten, anstelle des reinen Objektnamen über die ToString() Methode dargestellt zu bekommen, überschreibt man in der jeweiligen Klasse die ToString() Methode und gibt darin an, welche Daten ausgegeben werden sollen.
So in etwas sieht es im Debugger aus, wenn man ToString() nicht überschreibt:
Für, ich will es mal “Nicht so komplexe Klassen” nennen, kann man das auch im folgenden Stil machen.
public override string ToString() { return "Ausschreibungsstatus= " + this.Ausschreibungsstatus + " " + "Ausschreibungstext= " + this.Ausschreibungstext; }
Das ist schon besser und sieht in etwa so aussehen:
Schon besser, aber ….
Ich würde gerne ohne großen Schreibaufwand in jeder Klasse die Public Eigenschaften mit den enthaltenen Werten angezeigt bekommen.
Also musste ich mir hierfür etwas mehr generisches ausdenken.
Und wieder einmal lag die Lösung meines Problems in der Verwendung von Reflection.
Hier nun meine “generische” Methode zur Bildung einer für mich “sinnvollen” ToString() Ausgabe für meine komplexen Klassen.
public static string ClassPropertiesToString(object obj) { string retVal = obj.GetType().ToString() + "\n"; const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy; var sourceProperties = obj.GetType().GetProperties(Flags); foreach (PropertyInfo pi in sourceProperties) { if (pi.PropertyType.Namespace != "System") continue; retVal += string.Format("{0}:{1}\n", pi.Name, pi.GetValue(obj, null)); } return retVal; }
Ich denke der Code ist soweit Selbsterklärend, falls nicht, einfach einen Kommentar abgeben und fragen, dann erläutern wir die Details.
Hier noch der Vollständigkeit halber, das Ergebnis im Debugger:
Und bevor ich es vergesse.
So sieht dann die Überschreibung in der jeweiligen Klasse aus:
public override string ToString() { return Lager.Global.Common.Generic.ClassPropertiesToString(this); }
Gute Idee, als Verbesserungsvorschlag würde ich jedoch einen StringBuilder verwenden, gerade bei umfangreichen Klassen sollte dieses deutlich schneller sein:
public static string ClassPropertiesToString(object obj)
{
StringBuilder retVal = new StringBuilder();
retVal.AppendLine(string.Format(„{0}\n“, obj.GetType()));
const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
var sourceProperties = obj.GetType().GetProperties(Flags);
foreach (PropertyInfo pi in sourceProperties)
{
if (pi.PropertyType.Namespace != „System“)
continue;
retVal.AppendLine(string.Format(„{0}:{1}\n“, pi.Name, pi.GetValue(obj, null)));
}
return retVal.ToString();
}
Hi Alex,
da hast du recht zumindest auf dem Papier sollte das schneller sein, sauberer sieht es auch aus.
Danke für den Hinweis
HP
Für die „Nicht so komplexe“ Klassen kann man auch einfach das DebuggerDisplayAttribute verwenden.
http://msdn.microsoft.com/de-de/library/system.diagnostics.debuggerdisplayattribute.aspx
Danke,
die Variante kannte ich gar nicht.
Beste Grüße
HP
gute Idee, noch einfacher wäre es sich den String gleich schön formatiert als JSON ausgeben zu lassen. geht ganz flott mit dem Newton JSON.NET: http://json.codeplex.com/
string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
Übrigens, wenn man die ToString() Methode nicht missbrauchen kann/darf, dann gibt es noch die Möglichkeit sich einen eigenen Visualizer zu schreiben.
http://msdn.microsoft.com/de-de/library/zayyhzts.aspx