Entwickler-Ecke
Basistechnologien - Verbesserungsvorschläge / Bugreport
Flitzs - Do 19.06.08 23:41
Titel: Verbesserungsvorschläge / Bugreport
Hey,
vielleicht kennt Jemand von euch das Tool/Snippet ObjectDumper, da ich den Source von dem nirgends finden konnte, hab ich ihn versucht nachzuprogrammieren.
Da mehrer Leute sicher mehr Bugs finden als Einer, und da ich mir sicher bin das man da noch was verbessern kann, wäre ich dankbar wenn ihr euch das mal anseht.
Ja der Sinn für die dies nicht kennen, ein Objekt mit sämtlichen Members die interresant sind, über reflection, als String zurückgeben.
{} = IEnumerable
[] = Struct
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97:
| using System; using System.Reflection; using System.Collections;
namespace ODS { class Program { static void Main(string[] args) { } } public static class ObjectDumper { public static string Dump(object o) { string RetVal = ""; if (o == null) return "";
try {
if (o is IEnumerable && !(o is ValueType) && !(o is string)) { RetVal += "{"; foreach (object Item in (IEnumerable)o) { RetVal += Dump(Item);
if (Item is string) { RetVal = RetVal.Remove(RetVal.Length - 2); RetVal += ", "; } } if (RetVal.Length > 1) RetVal = RetVal.Substring(0, RetVal.Length - 2); RetVal += "}"; RetVal += Environment.NewLine;
} else if (o.GetType().IsClass && !(o is string)) { foreach (MemberInfo M in o.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance)) { PropertyInfo P = M as PropertyInfo; FieldInfo f = M as FieldInfo; if (P != null || f != null) RetVal += M.Name + " = " + Dump(f != null ? f.GetValue(o) : P.GetValue(o, null)); } RetVal += Environment.NewLine;
} else if (o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance).Length != 0) { FieldInfo[] FI = o.GetType().GetFields(); RetVal += "["; foreach (FieldInfo f in FI) { RetVal += f.Name + " = " + f.GetValue(o) + Environment.NewLine; } RetVal = RetVal.Remove(RetVal.Length - 2); RetVal += "]" + Environment.NewLine; }
else { RetVal += o.ToString() + Environment.NewLine;
}
return RetVal; } catch (Exception ex) { return "Fehler beim verarbeiten: " + ex.Message; } }
}
} |
mfg Flitzs
Moderiert von
Christian S.: Topic aus C# - Die Sprache verschoben am Do 19.06.2008 um 23:49
Christian S. - Do 19.06.08 23:49
Ist schon spät, daher guck ich mir das genauer erst morgen an. :-)
Auf jeden Fall eine sehr nützliche Funktion :zustimm:
Was mir direkt auffällt: Ich würde zum einen einen StringBuilder verwenden, welchen Du für die Rekursion auch als Parameter an die Funktion übergeben können solltest. Das sollte schneller sein und weniger Speicher verbrauchen als mit Strings zu arbeiten.
Außerdem würde ich versuchen, ein paar Caching-Funktionen einzubauen. So braucht man für einen Typ ja nur einmal die PropertyInfos abrufen, die kann man ja dann cachen.
//edit:
Noch eine weitere Idee: Man cached nicht nur die PropertyInfos, sondern cached für jeden Typ die komplette Methode, nach der er serialisiert wird. Man definiert einen solchen Delegate:
C#-Quelltext
1:
| private delegate void SerializeDelegate(Object o, StringBuilder sb); |
und hat ein Dictionary:
C#-Quelltext
1:
| private Dictionary<Type, SerializeDelegate> serializers; |
Dann braucht man die ganzen Fall-Unterscheidungen nur einmal pro Typ machen, ab da ruft man nur noch den korrekten Delegate aus dem Dictionary ab.
Flitzs - Fr 20.06.08 13:08
Danke für deine Antwort.
Das mit den StringBuilder hab ich mal so gemacht, allerdings hab ich den Global in der Klasse deklariert damit ich den nicht jedesmal als Parameter übergeben muss.
Ja das mit dem Chachen muss ich mir noch überlegen wie ich das mache, noch hab ich keine Idee wie ich das anstelle :D
mfg Flitzs
PS: Aktueller Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112:
| using System; using System.Reflection; using System.Collections;
namespace OD { class Program { static void Main(string[] args) { System.Collections.Generic.List<String> a = new System.Collections.Generic.List<string>() { "eins", "zwei", "drei" }; Console.WriteLine(ObjectDumper.Write(a)); Console.ReadLine(); } } public static class ObjectDumper { private static System.Text.StringBuilder SB; private static Boolean Err; private static String ErrMessage; public static string Write(object o) { SB = new System.Text.StringBuilder(); ErrMessage = ""; Err = false; Dump(o); return (!Err) ? SB.ToString() : ErrMessage ; } private static void Dump(object o) { if (o == null || Err == true) return;
try {
if (o is IEnumerable && !(o is ValueType) && !(o is string)) { SB.Append("{"); foreach (object Item in (IEnumerable)o) { Dump(Item);
if (Item is string) { SB.Remove(SB.ToString().Length - 2,2); SB.Append(", "); } } if (SB.ToString().Length > 1) SB = new System.Text.StringBuilder(SB.ToString().Substring(0, SB.ToString().Length - 2)); SB.Append ("}" + Environment.NewLine);
} else if (o.GetType().IsClass && !(o is string)) { foreach (MemberInfo M in o.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance)) { PropertyInfo P = M as PropertyInfo; FieldInfo f = M as FieldInfo; if (P != null || f != null) SB.Append(M.Name + " = "); Dump(f != null ? f.GetValue(o) : P.GetValue(o, null)); } SB.Append(Environment.NewLine);
} else if (o.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance).Length != 0) { FieldInfo[] FI = o.GetType().GetFields(); SB.Append("["); foreach (FieldInfo f in FI) SB.Append(f.Name + " = " + f.GetValue(o) + Environment.NewLine); SB.Remove(SB.ToString().Length - 2,2); SB.Append("]" + Environment.NewLine); }
else { SB.Append(o.ToString() + Environment.NewLine);
} } catch (Exception ex) { Err = true; ErrMessage = "Fehler beim verarbeiten: " + ex.Message; return; } }
}
} |
Kha - Fr 20.06.08 14:18
Titel: Re: Verbesserungsvorschläge / Bugreport
Flitzs hat folgendes geschrieben: |
Ja der Sinn für die dies nicht kennen, ein Objekt mit sämtlichen Members die interresant sind, über reflection, als String zurückgeben. |
Also einfach eine proprietäre Variante von
JSON [
http://james.newtonking.com/pages/json-net.aspx] :tongue: ? Nichts für ungut, aber da muss ich eben gleich an
Not Invented Here denken ;) . Als Übung aber z.B. wahrscheinlich perfekt, du zwingst mich geradezu zu einer F#-Implementierung :D .
PS: Ich denke, du meinst den ObjectDumper aus den C#-Samples. Sitzt im VS-Verzeichnis unter "Microsoft Visual Studio 9.0\Samples\1031\CSharpSamples.zip\LinqSamples\ObjectDumper".
Flitzs - Fr 20.06.08 14:30
Jop den meinte ich, ich hab ihn damals bei einer Microsoft Presentation der C# 3 new Feature gesehen. Ähm jo hätte ich früher gewusst das es den eh schon als sample gibt hätt ichs wohl gelassen aber so is es ne gute Übung zudem will ich ja noch das von Christian S. angesprochene Chachen einbauen ;)
mfg Flitzs
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!