Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从类中获取所有属性和子属性_C#_Reflection - Fatal编程技术网

C# 从类中获取所有属性和子属性

C# 从类中获取所有属性和子属性,c#,reflection,C#,Reflection,我使用反射来获取类名,需要获取类的所有子属性以及所有子属性的属性 我遇到了一个递归问题,项目被添加到了错误的列表中 我的代码如下: private List<Member> GetMembers(object instance) { var memberList = new List<Member>(); var childMembers = new List<Member>(); foreach (var propertyInfo

我使用反射来获取类名,需要获取类的所有子属性以及所有子属性的属性

我遇到了一个递归问题,项目被添加到了错误的列表中

我的代码如下:

private List<Member> GetMembers(object instance)
{
    var memberList = new List<Member>();
    var childMembers = new List<Member>();

    foreach (var propertyInfo in instance.GetType().GetProperties())
    {
        var member = new Member
        {
            Name = propertyInfo.PropertyType.IsList() ? propertyInfo.Name + "[]" : propertyInfo.Name,
            Type = SetPropertyType(propertyInfo.PropertyType),
        };

        if (propertyInfo.PropertyType.IsEnum)
        {
            member.Members = GetEnumValues(propertyInfo).ToArray();
        }

        if (propertyInfo.PropertyType.BaseType == typeof(ModelBase))
        {
            var childInstance = propertyInfo.GetValue(instance) ?? Activator.CreateInstance(propertyInfo.PropertyType);

            childMembers.AddRange(GetMembers(childInstance));

            member.Members = childMembers.ToArray();
        }

        if (propertyInfo.PropertyType.IsGenericType && (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>) ||
            propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
        {
            var itemType = propertyInfo.PropertyType.GetGenericArguments()[0];

            var childInstance = Activator.CreateInstance(itemType);

            childMembers.AddRange(GetMembers(childInstance));

            member.Members = childMembers.Distinct().ToArray();
        }

        memberList.Add(member);
    }

    return memberList;
}
private List GetMembers(对象实例)
{
var memberList=新列表();
var childMembers=新列表();
foreach(实例.GetType().GetProperties()中的var propertyInfo)
{
var成员=新成员
{
Name=propertyInfo.PropertyType.IsList()?propertyInfo.Name+“[]”:propertyInfo.Name,
Type=SetPropertyType(propertyInfo.PropertyType),
};
if(propertyInfo.PropertyType.IsEnum)
{
member.Members=GetEnumValues(propertyInfo.ToArray();
}
if(propertyInfo.PropertyType.BaseType==typeof(ModelBase))
{
var childInstance=propertyInfo.GetValue(实例)??Activator.CreateInstance(propertyInfo.PropertyType);
AddRange(GetMembers(childInstance));
member.Members=childMembers.ToArray();
}
if(propertyInfo.PropertyType.IsGenericType&&(propertyInfo.PropertyType.GetGenericTypeDefinition()==typeof(列表)||
propertyInfo.PropertyType.GetGenericTypeDefinition()==typeof(IList)))
{
var itemType=propertyInfo.PropertyType.GetGenericArguments()[0];
var childInstance=Activator.CreateInstance(itemType);
AddRange(GetMembers(childInstance));
member.Members=childMembers.Distinct().ToArray();
}
成员列表。添加(成员);
}
返回成员列表;
}

下面的方法行吗

public static IEnumerable<PropertyInfo> GetProperties(this Type type, int depth = 1)
{
    IEnumerable<PropertyInfo> getProperties(Type currentType, int currentDepth)
    {
        if (currentDepth >= depth)
            yield break;

        foreach (var property in currentType.GetProperties())
        {
            yield return property;

            foreach (var subProperty in getProperties(property.PropertyType,
                                                      currentDepth + 1))
            {
                yield return subProperty;
            }
        }
    }

    if (depth < 1)
        throw new ArgumentOutOfRangeException(nameof(depth));

    return getProperties(type, 0);    
}
产量

Console.WriteLine(string.Join(Environment.NewLine,
                  typeof(Foo).GetProperties(2)
                             .Select(p => $"{p.DeclaringType.Name}: {p.Name}")));
将是:

Foo: S
String: Chars
String: Length
Foo: I

我不能肯定,因为我不知道你的代码调试和测试它的知识;但是,我相信您的问题可能是因为您正在使用
childMembers
列表。如果不是这样,请告诉我

private List<Member> GetMembers(object instance)
{
    var memberList = new List<Member>();

    foreach (var propertyInfo in instance.GetType().GetProperties())
    {
        var childMembers = new List<Member>(); // Moved to here, so it's not shared among all propertyInfo iterations.
        var member = new Member
        {
            Name = propertyInfo.PropertyType.IsList() ? propertyInfo.Name + "[]" : propertyInfo.Name,
            Type = SetPropertyType(propertyInfo.PropertyType),
        };

        if (propertyInfo.PropertyType.IsEnum)
        {
            member.Members = GetEnumValues(propertyInfo).ToArray();
        }

        if (propertyInfo.PropertyType.BaseType == typeof(ModelBase))
        {
            var childInstance = propertyInfo.GetValue(instance) ?? Activator.CreateInstance(propertyInfo.PropertyType);

            childMembers.AddRange(GetMembers(childInstance));

            member.Members = childMembers.ToArray();
        }

        if (propertyInfo.PropertyType.IsGenericType && (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>) ||
            propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
        {
            var itemType = propertyInfo.PropertyType.GetGenericArguments()[0];

            var childInstance = Activator.CreateInstance(itemType);

            childMembers.AddRange(GetMembers(childInstance));

            member.Members = childMembers.Distinct().ToArray();
        }

        memberList.Add(member);
    }

    return memberList;
}
private List GetMembers(对象实例)
{
var memberList=新列表();
foreach(实例.GetType().GetProperties()中的var propertyInfo)
{
var childMembers=new List();//移动到此处,因此它不会在所有propertyInfo迭代中共享。
var成员=新成员
{
Name=propertyInfo.PropertyType.IsList()?propertyInfo.Name+“[]”:propertyInfo.Name,
Type=SetPropertyType(propertyInfo.PropertyType),
};
if(propertyInfo.PropertyType.IsEnum)
{
member.Members=GetEnumValues(propertyInfo.ToArray();
}
if(propertyInfo.PropertyType.BaseType==typeof(ModelBase))
{
var childInstance=propertyInfo.GetValue(实例)??Activator.CreateInstance(propertyInfo.PropertyType);
AddRange(GetMembers(childInstance));
member.Members=childMembers.ToArray();
}
if(propertyInfo.PropertyType.IsGenericType&&(propertyInfo.PropertyType.GetGenericTypeDefinition()==typeof(列表)||
propertyInfo.PropertyType.GetGenericTypeDefinition()==typeof(IList)))
{
var itemType=propertyInfo.PropertyType.GetGenericArguments()[0];
var childInstance=Activator.CreateInstance(itemType);
AddRange(GetMembers(childInstance));
member.Members=childMembers.Distinct().ToArray();
}
成员列表。添加(成员);
}
返回成员列表;
}

如果通过“将项目添加到错误列表”,您的意思是将一个成员的
childMembers
添加到另一个成员,这可能是因为您正在重用
childMembers
变量。将其移动到循环内,以实例化循环的每个交互。不需要
childMembers
可以保存删除它并插入
AddRange
just
member.Members=GetMembers(childInstance)。ToArray()
我没有提出这个建议,因为我不确定我有正确的OP解决方案,此外,为了简单起见,我试图使它尽可能接近OP的原始代码,但您是对的,它可以被删除:)
private List<Member> GetMembers(object instance)
{
    var memberList = new List<Member>();

    foreach (var propertyInfo in instance.GetType().GetProperties())
    {
        var childMembers = new List<Member>(); // Moved to here, so it's not shared among all propertyInfo iterations.
        var member = new Member
        {
            Name = propertyInfo.PropertyType.IsList() ? propertyInfo.Name + "[]" : propertyInfo.Name,
            Type = SetPropertyType(propertyInfo.PropertyType),
        };

        if (propertyInfo.PropertyType.IsEnum)
        {
            member.Members = GetEnumValues(propertyInfo).ToArray();
        }

        if (propertyInfo.PropertyType.BaseType == typeof(ModelBase))
        {
            var childInstance = propertyInfo.GetValue(instance) ?? Activator.CreateInstance(propertyInfo.PropertyType);

            childMembers.AddRange(GetMembers(childInstance));

            member.Members = childMembers.ToArray();
        }

        if (propertyInfo.PropertyType.IsGenericType && (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>) ||
            propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
        {
            var itemType = propertyInfo.PropertyType.GetGenericArguments()[0];

            var childInstance = Activator.CreateInstance(itemType);

            childMembers.AddRange(GetMembers(childInstance));

            member.Members = childMembers.Distinct().ToArray();
        }

        memberList.Add(member);
    }

    return memberList;
}