我正在尝试遍历一个类及其子类以获取随其传递的值。
这是我的班级:
public class MainClass
{
bool IncludeAdvanced { get; set; }
public ChildClass1 ChildClass1 { get; set; }
public ChildClass2 ChildClass2 { get; set; }
}
到目前为止,这是我的代码
GetProperties<MainClass>();
private void GetProperties<T>()
{
Type classType = typeof(T);
foreach (PropertyInfo property in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
WriteToLog(property.Name + ": " + property.PropertyType + ": " + property.MemberType);
GetProperties<property>();
}
}
两个问题:
希望这一切都有道理。如果没有,请不要犹豫,我会尽力澄清。
由于
答案 0 :(得分:6)
您可以轻松地将其重写为没有泛型的递归:
private void GetProperties<T>()
{
GetProperties(typeof(T));
}
private void GetProperties(Type classType)
{
foreach (PropertyInfo property in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
WriteToLog(property.Name + ": " + property.PropertyType + ": " + property.MemberType);
GetProperties(property.PropertyType);
}
}
在你的第二个问题上不确定“如果它不是一个类,我如何从属性项中获取值”(当我们想出来时我会编辑/更新)
答案 1 :(得分:5)
克里斯已经回答了你问题的第一部分,所以我不再重复了。对于第二部分,只要您拥有MainClass
的实例,就可以使用(恰当命名的)PropertyInfo.GetValue method:
object value = property.GetValue(myInstance, null);
(如果您使用的是.NET 4.5,则可以omit the second (null
) parameter。但早期版本需要它。)
最后,你的代码看起来像这样(我无耻地复制并扩展了Chris的版本)(未经测试):
private void GetProperties<T>(T instance)
{
GetProperties(typeof(T), instance);
}
private void GetProperties(Type classType, object instance)
{
foreach (PropertyInfo property in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
WriteToLog(property.Name + ": " + property.PropertyType + ": " + property.MemberType);
object value = property.GetValue(instance, null);
if (value != null) {
WriteToLog(value.ToString());
GetProperties(property.PropertyType, value);
}
}
}
请注意,如果您的任何对象在VB中使用索引属性(C#indexers或properties with parameters),则此代码将失败。在这种情况下,需要为GetValue提供适当的索引或参数。
答案 2 :(得分:0)
关于第二个问题,如果要从属性项中获取值,则必须提供Type的对象。海因兹已经解释了如何通过财产获得价值。我提供没有泛型的shell版本。
private static void ResolveTypeAndValue(object obj)
{
var type = obj.GetType();
foreach (var p in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
{
if (p.PropertyType.IsClass && p.PropertyType != typeof(string))
{
var currentObj = p.GetValue(obj);
ResolveTypeAndValue(currentObj);
}
else
Console.WriteLine("The value of {0} property is {1}", p.Name, p.GetValue(obj));
}
}
答案 3 :(得分:0)
public IEnumerable<PropertyInfo> GetProperties(Type type)
{
//Just to avoid the string
if (type == typeof(String)) return new PropertyInfo[] { };
var properties = type.GetProperties().ToList();
foreach (var p in properties.ToList())
{
if (p.PropertyType.IsClass)
properties.AddRange(GetProperties(p.PropertyType));
else if (p.PropertyType.IsGenericType)
{
foreach (var g in p.PropertyType.GetGenericArguments())
{
if (g.IsClass)
properties.AddRange(GetProperties(g));
}
}
}
return properties;
}
尝试这只在属性
时迭代属性