问题描述
我正在处理 Reflection ,但我在进行递归时卡住了.
I am working on the Reflection , but i am stuck while doing the recursion.
代码:
public class User { public string Name; public int Number; public Address Address; } public class Address { public string Street; public string State; public string Country; }
现在我正在打印这些值.
now i am printing the values.
Type t = user.GetType(); PropertyInfo[] props = t.GetProperties(); foreach (PropertyInfo prp in props) { if(!prp.GetType().IsPrimitive && prp.GetType().IsClass) { // Get the values of the Inner Class. // i am stucked over here , can anyone help me with this. Type ty = prp.GetType(); var prpI = ty.GetProperties(); //var tp = ty.GetType().; foreach (var propertyInfo in prpI) { var value = propertyInfo.GetValue(prp); var stringValue = (value != null) ? value.ToString() : ""; console.WriteLine(prp.GetType().Name + "." + propertyInfo.Name+" Value : " +stringValue); } } else { var value = prp.GetValue(user); var stringValue = (value != null) ? value.ToString() : ""; console.writeline(user.GetType().Name + "." + prp.Name+" Value : " +stringValue); } }
我想知道如何确定该属性是类还是基元.如果是类,则进行递归.
i want to know how to find out whether the property is a class or the primitive. and do the recursion if it is a class.
推荐答案
首先,如果要访问类型的属性,请确保使用具有属性的类型:
First of all, if you want to access the properties of a type, ensure you are using a type which has properties:
public class User { public string Name{get;set;} public int Number{get;set;} public Address Address{get;set;} } public class Address { public string Street{get;set;} public string State{get;set;} public string Country{get;set;} }
其次,prp.GetType() 将始终返回 PropertyInfo.您正在寻找 prp.PropertyType,它将返回属性的类型.
Second, prp.GetType() will always return PropertyInfo. You are looking for prp.PropertyType, which will return the Type of the property.
此外,if(!prp.GetType().IsPrimitive && prp.GetType().IsClass) 不会按照你想要的方式工作,因为 String代码> 例如是一个类,也不是一个原始类型.最好使用 prp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary".
Also, if(!prp.GetType().IsPrimitive && prp.GetType().IsClass) won't work the way you want, because String e.g. is a class and also not a primitive. Better use prp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary".
最后但并非最不重要的是,要使用递归,您实际上必须将代码放入方法中.
Last but not least, to use recursion, you actually have to put your code into a method.
这是一个完整的例子:
IEnumerable<string> GetPropertInfos(object o, string parent=null) { Type t = o.GetType(); PropertyInfo[] props = t.GetProperties(BindingFlags.Public|BindingFlags.Instance); foreach (PropertyInfo prp in props) { if(prp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary") { // fix me: you have to pass parent + "." + t.Name instead of t.Name if parent != null foreach(var info in GetPropertInfos(prp.GetValue(o), t.Name)) yield return info; } else { var value = prp.GetValue(o); var stringValue = (value != null) ? value.ToString() : ""; var info = t.Name + "." + prp.Name + ": " + stringValue; if (String.IsNullOrWhiteSpace(parent)) yield return info; else yield return parent + "." + info; } } }
这样使用:
var user = new User { Name = "Foo", Number = 19, Address = new Address{ Street="MyStreet", State="MyState", Country="SomeCountry" } }; foreach(var info in GetPropertInfos(user)) Console.WriteLine(info);
它会输出
User.Name: Foo User.Number: 19 User.Address.Street: MyStreet User.Address.State: MyState User.Address.Country: SomeCountry