オブジェクトのすべてのプロパティを表示したいと思います。オブジェクトを表示したいのですが。 perlのようなものData::Dumper
またはphpのvar_dump
。GetPropertiesを使用してオブジェクトをトラバースする
私は自分のコードを試しましたが、最終的にこれを私がオンラインで見つけました。しかし、すべてのコードは、自身への参照を持つオブジェクトによって引き起こされるStackOverFlowException
で失敗します。
以下の例では、オブジェクトCurrentThread
を印刷しようとしていますが、これは同じオブジェクトを指すCurrentThread
というプロパティを持つタイプのスレッドのクラスであり、無限ループに詰まっています。
.Net
の方法がありますか。これについてはわかりません。解決方法を教えてください。おそらく、オブジェクト/クラスに親プロパティを持つ子があり、無限ループが発生する可能性があると考えています。
オブジェクトを他の言語でダンプする方法があるので、もちろんこのプローブが検出されたのは初めてではありません。
どうすれば解決できますか?
私だけではなく、(例として)、すべてのデータをプリントアウトしたい:
obj.arr = string[]
私が必要になります。
obj.arr = ["a", "b"]
誰も私のために何か良いの入力を持っていますか?
編集:私はこの例を次のように書き直しました。(以下の元々の質問の古いコード)。
電話番号:
var cache = new HashSet<object>();
var sb = new StringBuilder();
ParseObject(System.Threading.Thread.CurrentThread, 0, sb, cache);
方法:
private void ParseObject(object o, int level, StringBuilder sb, HashSet<object> cache) {
if (o == null) {
sb.Append("NULL");
return;
}
var type = o.GetType();
switch (type.FullName)
{
case "System.String":
sb.Append(o).AppendLine();
return;
case "System.Int16":
case "System.Int32":
case "System.Int64":
sb.Append(o).AppendLine();
return;
case "System.Single":
sb.Append(o).AppendLine();
return;
case "System.Decimal":
sb.Append(o).AppendLine();
return;
case "System.Double":
sb.Append(o).AppendLine();
return;
case "System.DateTime":
sb.Append(((DateTime)o).ToString("yyyy-MM-dd HH:mm:ss")).AppendLine();
return;
}
if (cache.Contains(o))
{
sb.Append("REFERENCE TO OLD OBJECT");
return;
}
cache.Add(o);
if (o is IEnumerable<object>) {
IEnumerable<object> io = o as IEnumerable<object>;
int i = 0;
foreach (object o1 in io) {
sb.Append("[" + i + "] = ");
ParseObject(o1, level+1, sb, cache);
}
return;
}
var hasProperties = false;
foreach (PropertyInfo prop in type.GetProperties()) {
hasProperties = true;
sb.Append(new string('\t', level));
sb.Append(prop.Name).Append("=");
object element = prop.GetValue(o);
ParseObject(element, level + 1, sb, cache);
}
if (!hasProperties) {
sb.Append(o).AppendLine();
}
}
OLD例:
var sb = new StringBuilder();
PrintProperties(System.Threading.Thread.CurrentThread, 0, sb);
public void PrintProperties(object obj, int indent, StringBuilder sb)
{
if (obj == null) return;
string indentString = new string(' ', indent);
Type objType = obj.GetType();
PropertyInfo[] properties = objType.GetProperties();
foreach (PropertyInfo property in properties)
{
object propValue = property.GetValue(obj, null);
var elems = propValue as IList;
if (elems != null)
{
foreach (var item in elems)
{
PrintProperties(item, indent + 3, sb);
}
}
else
{
// This will not cut-off System.Collections because of the first check
if (property.PropertyType.Assembly == objType.Assembly)
{
//Console.WriteLine("{0}{1}:", indentString, property.Name);
sb.AppendLine(string.Format("{0}{1}:", indentString, property.Name));
PrintProperties(propValue, indent + 2, sb);
}
else
{
//Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
sb.AppendLine(string.Format("{0}{1}: {2}", indentString, property.Name, propValue));
}
}
}
}
を生成します。私はObjectReferenceEqualityComparer(私自身の実装)を使ってすべての参照を保持するHashSetを持つことで、このような問題を解決しました。あなたが既知のリファレンスプリントを見つけた場合は、 ""を参照してください。すべてのオブジェクトにポインタアドレスを出力します。これがあれば、その人を探してあなたの情報を見つけることができます。 –
情報をありがとう、私はより良い概観を得るために少し方法を書き直し、私は後でコードをきれいにすることができます。しかし、私はまだStackOverflowExceptionを取得します。助言がありますか? – MrApnea