2

我正在尝试遍历一个类,它是子类来获取与它一起传递的值。

这是我的课:

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. 如果它不是一个类,我如何从属性项中获取值?

希望这一切都有意义。如果没有,请不要犹豫,我会尽力澄清。

谢谢

4

4 回答 4

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

不确定你的第二个问题“如果它不是一个类,我如何从属性项中获取值”(当我们弄清楚时我会编辑/更新)

于 2013-05-01T11:34:04.840 回答
5

克里斯已经回答了你问题的第一部分,所以我不会重复。对于第二部分,只要你有一个实例MainClass,你就可以使用(恰当命名的)PropertyInfo.GetValue 方法

object value = property.GetValue(myInstance, null);

(如果您使用 .NET 4.5,则可以省略第二个 ( null) 参数。不过,早期版本需要它。)

最后,您的代码可能如下所示(我无耻地复制和扩展了 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);
        }
    }
}

请注意,如果您的任何对象使用索引属性(C#索引器或VB 中带有参数的属性),此代码将失败。在这种情况下,需要为 GetValue 提供适当的索引或参数。

于 2013-05-01T13:08:32.427 回答
0

关于你的第二个问题,如果你想从属性项中获取值,你必须提供类型的对象。Heinzi 解释了如何通过属性获取价值。我提供了一个没有泛型的 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));
        }
    }
于 2013-05-01T13:36:34.850 回答
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;

    }

试试这个,只有当它是类时才迭代属性

于 2013-05-01T13:38:03.600 回答