我想知道是否有人可以帮助我 - 我没有做太多的反思,但理解基本原则。
我正在尝试做什么:
我正在开发一个类,该类收集有关本地系统,网络等的大量信息,以用于自动错误报告。我不是每次添加新属性时都必须更改我的测试工具,而是(理想情况下)能够将该批次序列化为XML字符串并将其显示在文本框中。
不幸的是,框架不会在只读属性上使用默认的XML序列化程序(几乎所有的都是),因为它们不会正确反序列化
[不确定我同意任何序列化必须可反序列化的假设 - MS说这是“按设计”的功能,我想我可以理解 - 也许是一个标记,表明它应该被序列化无论如何会有利吗?]
最初的方法是使属性可以获取和设置(在setter上有抛出异常),但之后整理它的工作量似乎有点过分,我希望这些属性在最终版本中是只读的
我需要帮助:
我目前的计划是使用反射递归迭代我最顶层的聚类的每个(公共)属性。问题是,我见过的样本不会递归处理。另外,我只想检查一个对象的属性,如果它在我的一个程序集中 - 否则只需在它上面调用.ToString。
如果我没有将检查限制在我的程序集中,我假设我会得到一个字符串,然后包含一个长度,而该长度又会有.Tostring方法......
出于本项目的目的,我几乎保证我的代码中没有循环引用,因为这只会用作开发工具所以我不是太担心它偶尔会肆无忌惮。
我很欣赏一些例子/建议。
非常感谢提前。
答案 0 :(得分:3)
这有望让你入门。它将树直接打印到控制台,因此您需要调整为输出XML。然后更改IsMyOwnType方法以过滤掉您感兴趣的程序集,现在它只关心同一程序集中的类型。
Shared Sub RecurseProperties(o As Object, level As Integer)
For Each pi As PropertyInfo In o.GetType().GetProperties()
If pi.GetIndexParameters().Length > 0 Then Continue For
Console.Write(New String(" "c, 2 * level))
Console.Write(pi.Name)
Console.Write(" = ")
Dim propValue As Object = pi.GetValue(o, Nothing)
If propValue Is Nothing Then
Console.WriteLine("<null>")
Else
If IsMyOwnType(pi.PropertyType) Then
Console.WriteLine("<object>")
RecurseProperties(propValue, level+1)
Else
Console.WriteLine(propValue.ToString())
End If
End If
Next
End Sub
Shared Function IsMyOwnType(t As Type) As Boolean
Return t.Assembly Is Assembly.GetExecutingAssembly()
End Function
答案 1 :(得分:2)
c#上的扩展版本用于任何对象
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Extensions
{
public static class ObjectExtension
{
public static string ToStringProperties(this object o)
{
return o.ToStringProperties(0);
}
public static string ToStringProperties(this object o, int level)
{
StringBuilder sb = new StringBuilder();
string spacer = new String(' ', 2 * level);
if (level == 0) sb.Append(o.ToString());
sb.Append(spacer);
sb.Append("{\r\n");
foreach (PropertyInfo pi in o.GetType().GetProperties())
{
if (pi.GetIndexParameters().Length == 0)
{
sb.Append(spacer);
sb.Append(" ");
sb.Append(pi.Name);
sb.Append(" = ");
object propValue = pi.GetValue(o, null);
if (propValue == null)
{
sb.Append(" <null>");
} else {
if (IsMyOwnType(pi.PropertyType))
{
sb.Append("\r\n");
sb.Append(((object)propValue).ToStringProperties(level + 1));
} else{
sb.Append(propValue.ToString());
}
}
sb.Append("\r\n");
}
}
sb.Append(spacer);
sb.Append("}\r\n");
return sb.ToString();
}
private static bool IsMyOwnType(Type t)
{
return (t.Assembly == Assembly.GetExecutingAssembly());
}
}
}