オブジェクトを再帰的にダンプする。
バカな事をして再帰しっぱなしってことがない様にMaxRecursiveDepthなんて入れたが、returnするときに忘れずにデクリメントするのが面倒。
・・・・・・そうだfinallyに入れよう。
int MaxRecursiveDepth =100; int mRecursiveDepth = 0; public string ToStringRecursive(object o) { if (mRecursiveDepth >= MaxRecursiveDepth) { mRecursiveDepth--; return ""; } mRecursiveDepth++; string indent = ""; for (int r = 0; r < (mRecursiveDepth -1); r++) { indent += "\t"; } Type t = o.GetType(); if (t.IsPrimitive) { if (o == null) { mRecursiveDepth--; return "null"; } mRecursiveDepth--; return o.ToString(); } if (t.IsValueType) { if (o == null) { mRecursiveDepth--; return "null"; } mRecursiveDepth--; return o.ToString(); } FieldInfo[] fi = t.GetFields(); if (fi == null) { if (o == null) { mRecursiveDepth--; return "null"; } mRecursiveDepth--; return o.ToString(); } if (fi.Length == 0) { mRecursiveDepth--; return o.ToString(); } if (fi[0].Name == "Empty") { if (o == null) return "null"; mRecursiveDepth--; return o.ToString(); } StringWriter w = new StringWriter(); for (int i = 0; i < fi.Length; i++) { object oo = fi[i].GetValue(o); Type tt = oo.GetType().GetInterface("System.Collections.ICollection"); if (tt != null) { System.Collections.ICollection ic = (System.Collections.ICollection)oo; System.Collections.IEnumerator e = ic.GetEnumerator(); int ec = 0; while (e.MoveNext()) { Type et = e.Current.GetType(); w.Write(indent); w.Write(fi[i].Name); w.Write("[" + ec.ToString() + "]:"); if (et.IsPrimitive || et.IsValueType || et.Name == "String") { } else { w.WriteLine(); } w.WriteLine(ToStringRecursive(e.Current)); ec++; } } else { w.Write(indent); w.Write(fi[i].Name); w.Write(":"); if (fi[i].FieldType.IsPrimitive || fi[i].FieldType.IsValueType || fi[i].FieldType.Name == "String") { } else { w.WriteLine(); } w.WriteLine(ToStringRecursive(oo)); } } mRecursiveDepth--; return w.ToString(); }
これを元にJSONSerializerを書く。
GetFields使っているがGetMembersしてGetField,GetPropertyしないとPropertyが出力できない。あと、privateだとどうなる?