如何使用反射来迭代包括IEnumerable集合在内的所有属性?

问题描述 投票:0回答:1

假设我有以下课程;

public class Foo
{
    public string Reference { get; set; }
    public CompanyModel Company { get; set; }
    public CallDataModel CallData { get; set; }
}

public class CompanyModel
{
    public string Name { get; set; }
}

public class CallDataModel
{
    public IEnumerable<CallModel> Item { get; set; }
}

public class CallModel
{
    public string Name { get; set; }
    public int Value { get; set; }
}

使用反射,请有人可以帮助我遍历所有属性,包括IEnumerable集合。

我希望能够在递归方法中绘制出每个属性名称和对应的值。

例如;

public void GetPropertiesRescursively<T>(this T model)
{
    foreach (PropertyInfo prop in model.GetType().GetProperties())
    {
        // Do something
    }
}

提前感谢。

编辑:

这与我尝试达到的目标一致,但是我不确定是否要迭代IEnumerable。

public static List<String> GetPropertiesRescursively<T>(this T model)
{

    List<String> result = new List<String>();

    BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;

    foreach (PropertyInfo prop in model.GetType().GetProperties(flags))
    {

        string className = model.GetType().Name;
        string propertyName = prop.Name;
        object propertyValue = model.GetType().GetProperty(propertyName).GetValue(model, null);

        if (prop.PropertyType.IsClass)
        {
            GetPropertiesRescursively(propertyValue);
        }
        else
        {
            if (prop.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)))
            {
                foreach (PropertyInfo otherProp in (IEnumerable)prop.GetType().GetProperties(flags))
                {
                    GetPropertiesRescursively(otherProp);
                }
            }
            else
            {
                // Show property name and value e.g. SomeClass.SomeProperty=1
                result.Add(string.Format("{0}.{1}={2}", className, propertyName, propertyValue));
            }
        }

    };

    return result;

}
c# reflection ienumerable
1个回答
0
投票

您可以使用Reflection遍历属性。例如

private static void GetProperties<T>(T obj)
{
    if (obj == null) return;
    Type objType = obj.GetType();

    PropertyInfo[] properties = obj.GetType().GetProperties();
    foreach (PropertyInfo property in properties)
    {
        // Check if its a collection
        if (property.IsEnumerable())
        {
            if(property.GetValue(obj,null) is IEnumerable elems)
            {
                foreach (var item in elems)
                {
                    GetProperties(item);
                }
            }
        }
        else
        {
            var propValue = property.GetValue(obj, null);

             // If it is User Defined Type, Recursively loop again
            if (property.PropertyType.Assembly == objType.Assembly)
            {
                GetProperties(propValue);
            }
            else
            {
                Console.WriteLine($"{property.Name} = {propValue}");
            }

        }
    }
}

IsEnumerable()的定义如下。

public static class Extensions
{
    public static bool IsEnumerable(this PropertyInfo propertyInfo)
    {
        if(!propertyInfo.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)) )
        {
            return false;

        }
        return propertyInfo.PropertyType != typeof(String);
    }
}

[检查Enumerable时,需要更改String,可以将其检测为IEnumerable<char>

Demo Code

© www.soinside.com 2019 - 2024. All rights reserved.