循环使用类和子类来检索C#中的属性和值

时间:2013-05-01 11:27:53

标签: c# class typeof getproperties

我正在尝试遍历一个类及其子类以获取随其传递的值。

这是我的班级:

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>();
    }
}

两个问题:

  1. 如果它是一个类,我将传递给GetProperties,传递子类,然后循环遍历它的属性?
  2. 如果属性项不是类,我如何从属性项中获取值?
  3. 希望这一切都有道理。如果没有,请不要犹豫,我会尽力澄清。

    由于

4 个答案:

答案 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#indexersproperties 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;

    }

尝试这只在属性

时迭代属性