积极答复者
请教,反射时怎样可以遍历List的对象

问题
-
想写一个函数,把某个对象展现到一个TreeView控件。因为这个对象中有成员变量是List<A>类型,用到递归调用。写了个初稿如下,debug下面这段代码时,VS能够知道lstObj中A的类型和个数。既然VS能知道,应当是有办法能遍历A的对象并递归调用。尝试过,可以把A的类型取到一个String类型里,但不知怎样取到A的个数和对象。public static void Object2TreeNode(Object obj, TreeNodeCollection treeNode){FieldInfo[] fields = obj.GetType().GetFields();
TreeNode tn;
foreach (FieldInfo field in fields){if (field.FieldType.IsGenericType){tn = new TreeNode(field.Name);
Object lstObj = field.GetValue(obj);
Type typeLst = lstObj.GetType();
//foreach ()//{//Object2TreeNode()//}}else{tn = new TreeNode(field.Name + "-" + field.GetValue(obj).ToString());}treeNode.Add(tn);}}请各位专家帮忙。
答案
-
你这里的object是一个实体,你只是想要知道这个实体的所有可见信息吧,如果知道类型的话就更简单了,直接一个强转就成强类型了,爱干嘛干嘛。如果不知道,那么就只有枚举所有变量、属性、函数(如 GetMethods ),然后用invoke方式来调用函数并获得返回值(函数调用比较危险,获取变量和属性还是可以的),还是一个蛮庞大的任务。
看 Type 类的成员介绍,该有的就都有了
霸王- 已标记为答案 ColinLeung 2010年3月12日 6:55
-
你好,
参考下面代码试试。
protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { this.TreeView2.CheckedNodes.Clear(); TreeNode tn = new TreeNode("RootNode"); this.GenerateNode(ref tn); this.TreeView2.Nodes.Add(tn); } } public TreeNode GenerateNode(ref TreeNode tn) { Test t = new Test(); t.Name = "TestName"; List<SubTest> subTestList = new List<SubTest>(); for (int i = 0; i < 2; i++) { SubTest st = new SubTest(); st.SubName = "SubName" + i.ToString(); List<int> intList = new List<int>(); for (int k = 0; k < 2; k++) { intList.Add(k); } st.IntList = intList; subTestList.Add(st); } t.ListObj = subTestList; ReflectFields(ref tn, t); return tn; } public void ReflectFields(ref TreeNode root, object o) { PropertyInfo[] fis = o.GetType().GetProperties(); if (fis.Length != 0) { foreach (PropertyInfo item in fis) { if (item.GetValue(o, null).GetType().IsGenericType) { TreeNode tn = new TreeNode(item.Name); object obj = item.GetValue(o, null); Type objType = obj.GetType(); int count = Convert.ToInt32(objType.GetProperty("Count").GetValue(obj, null)); for (int i = 0; i < count; i++) { object listItem = objType.GetProperty("Item").GetValue(obj, new object[] { i }); ReflectFields(ref tn, listItem); } root.ChildNodes.Add(tn); } else { TreeNode tn = new TreeNode(item.Name + "_" + item.GetValue(o, null).ToString()); root.ChildNodes.Add(tn); } } } else { TreeNode tn = new TreeNode(o.GetType().ToString()+"_"+o.ToString()); root.ChildNodes.Add(tn); } } public class Test { public string Name { get; set; } public List<SubTest> ListObj { get; set; } } public class SubTest { public string SubName { get; set; } public List<int> IntList { get; set; } }
Microsoft Online Community Support- 已标记为答案 KeFang Chen 2010年3月15日 1:40
全部回复
-
你这里的object是一个实体,你只是想要知道这个实体的所有可见信息吧,如果知道类型的话就更简单了,直接一个强转就成强类型了,爱干嘛干嘛。如果不知道,那么就只有枚举所有变量、属性、函数(如 GetMethods ),然后用invoke方式来调用函数并获得返回值(函数调用比较危险,获取变量和属性还是可以的),还是一个蛮庞大的任务。
看 Type 类的成员介绍,该有的就都有了
霸王- 已标记为答案 ColinLeung 2010年3月12日 6:55
-
你好,
参考下面代码试试。
protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { this.TreeView2.CheckedNodes.Clear(); TreeNode tn = new TreeNode("RootNode"); this.GenerateNode(ref tn); this.TreeView2.Nodes.Add(tn); } } public TreeNode GenerateNode(ref TreeNode tn) { Test t = new Test(); t.Name = "TestName"; List<SubTest> subTestList = new List<SubTest>(); for (int i = 0; i < 2; i++) { SubTest st = new SubTest(); st.SubName = "SubName" + i.ToString(); List<int> intList = new List<int>(); for (int k = 0; k < 2; k++) { intList.Add(k); } st.IntList = intList; subTestList.Add(st); } t.ListObj = subTestList; ReflectFields(ref tn, t); return tn; } public void ReflectFields(ref TreeNode root, object o) { PropertyInfo[] fis = o.GetType().GetProperties(); if (fis.Length != 0) { foreach (PropertyInfo item in fis) { if (item.GetValue(o, null).GetType().IsGenericType) { TreeNode tn = new TreeNode(item.Name); object obj = item.GetValue(o, null); Type objType = obj.GetType(); int count = Convert.ToInt32(objType.GetProperty("Count").GetValue(obj, null)); for (int i = 0; i < count; i++) { object listItem = objType.GetProperty("Item").GetValue(obj, new object[] { i }); ReflectFields(ref tn, listItem); } root.ChildNodes.Add(tn); } else { TreeNode tn = new TreeNode(item.Name + "_" + item.GetValue(o, null).ToString()); root.ChildNodes.Add(tn); } } } else { TreeNode tn = new TreeNode(o.GetType().ToString()+"_"+o.ToString()); root.ChildNodes.Add(tn); } } public class Test { public string Name { get; set; } public List<SubTest> ListObj { get; set; } } public class SubTest { public string SubName { get; set; } public List<int> IntList { get; set; } }
Microsoft Online Community Support- 已标记为答案 KeFang Chen 2010年3月15日 1:40
-
就递归调用问题,你这里有一个类型是 List<A> 的成员变量(或者属性,这里假设是成员变量吧,一样),那么就这么干。
Object2TreeNode(object obj) { Type t = obj.GetType(); // 显示等操作,略 // 获取所有成员,如果知道成员名,则可以不用这一步,直接到 InvokeMember 那里 FieldInfo[] fields = t.GetFields(); for(int i = 0; i < fields.Length; i++) { // 挨个找所有成员的类型,具体对应什么类型最好debug一下 if(fields[i].FieldType == "List") { // 获取这个成员的内容 List<object> list = t.InvokeMember("", BindingFlags.GetField, null, obj, null); foreach(object o in list) { // 这里就可以递归了 Object2TreeNode(o); } } } }
霸王 -
KeFang Chen<abbr class="affil">MSFT</abbr><abbr class="affil">, 版主的也对,方式不同而已
if (item.GetValue(o, null).GetType().IsGenericType)
{
TreeNode tn = new TreeNode(item.Name);
object obj = item.GetValue(o, null); // 这里就获得了列表的实例 List<object>
Type objType = obj.GetType();
int count = Convert.ToInt32(objType.GetProperty("Count").GetValue(obj, null)); // =obj.Count
for (int i = 0; i < count; i++)
{
object listItem = objType.GetProperty("Item").GetValue(obj, new object[] { i }); // = obj.Item[i]
ReflectFields(ref tn, listItem); // 递归
}
root.ChildNodes.Add(tn);
}
</abbr>
霸王