![](/img/trans.png)
[英]GetValue from list of GetProperties without an instantiated object using reflection
[英]Traverse an object using GetProperties
我想看到一个对象的所有属性,我想看到一个对象打印出来。 像perls Data::Dumper
或php的var_dump
。
我已经尝试了自己的代码,但最后尝试了我在网上找到的。 但是,每个代码都会因为对象具有对自身的引用而导致StackOverFlowException
失败。
在下面的例子中,我试图打印出对象CurrentThread
但这是一个类型为Thread的类,它有一个名为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();
}
}
旧例子:
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));
}
}
}
}
您可以使用Json.Net进行简单快速的序列化
Console.WriteLine(JsonConvert.SerializeObject(
System.Threading.Thread.CurrentThread,
Formatting.Indented,
new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
}));
这将产生
{
"ManagedThreadId": 9,
"ExecutionContext": {},
"Priority": 2,
"IsAlive": true,
"IsThreadPoolThread": false,
"IsBackground": false,
"ThreadState": 0,
"ApartmentState": 1,
"CurrentUICulture": "en-US",
"CurrentCulture": "en-US",
"Name": null
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.