C# 使用泛型类型的反射属性名称

C# 使用泛型类型的反射属性名称,c#,generics,reflection,C#,Generics,Reflection,在我的反射方法中,我很难获得所有正确的值。当我开始横向遍历模型时,似乎该方法在到达ItemData类时停止查找横向的IEnumerables。(即,它将只遍历ItemId和Active,但不会将IEnumerables识别为属性) 我需要它做的是获取整个类型中各种IEnumerable的名称。例如,当类型通过代码传递时,以下项目将添加到列表中:内容、数据、ItemAttributes、ItemUrls和InventoryInformation 模型: public class ModelBase

在我的反射方法中,我很难获得所有正确的值。当我开始横向遍历模型时,似乎该方法在到达ItemData类时停止查找横向的IEnumerables。(即,它将只遍历ItemId和Active,但不会将IEnumerables识别为属性)

我需要它做的是获取整个类型中各种IEnumerable的名称。例如,当类型通过代码传递时,以下项目将添加到列表中:内容、数据、ItemAttributes、ItemUrls和InventoryInformation

模型:

public class ModelBase<TModel>
{
    public string Error { get; set; }
    public IEnumerable<TModel> Content { get; set; }
}

public class ItemContent
{
    public IEnumerable<ItemData> Data { get; set; }
    public int Total { get; set; }
}

public class ItemData
{
    public long ItemId { get; set; }
    public bool Active { get; set; }
    IEnumerable<ItemAttribute> ItemAttributes { get; set; }
    IEnumerable<string> ItemUrls { get; set; }
    IEnumerable<InventoryInformation> InventoryInformation { get; set; }
}

public class ItemAttribute
{
    public string AttributeName { get; set; }
    public bool IsRequired { get; set; }
}

public class InventoryInformation
{
    public int AreaId { get; set; }
    public double Price { get; set; }
}
公共类模型库
{
公共字符串错误{get;set;}
公共IEnumerable内容{get;set;}
}
公共类ItemContent
{
公共IEnumerable数据{get;set;}
公共整数总计{get;set;}
}
公共类ItemData
{
公共长项目ID{get;set;}
公共bool活动{get;set;}
IEnumerable ItemAttributes{get;set;}
IEnumerable itemURL{get;set;}
IEnumerable清单信息{get;set;}
}
公共类ItemAttribute
{
公共字符串AttributeName{get;set;}
需要公共布尔值{get;set;}
}
公共类目录信息
{
公共int AreaId{get;set;}
公共双价{get;set;}
}
守则:

// T is ModelBase<TModel> in this context...
// TModel is ItemContent in this context...
GetProperties(typeof(T));

private void GetProperties(Type classType)
{
    foreach (PropertyInfo property in classType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        if (property.PropertyType.IsGenericType && (property.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>)))
        {
            ValuesToList.Add(property.Name);

            foreach (Type nestedType in property.PropertyType.GetGenericArguments())
            {
                GetProperties(nestedType);
            }
        }
    }
}

private List<string> ValuesToList { get; set; }
//T在此上下文中是ModelBase。。。
//TModel是此上下文中的ItemContent。。。
GetProperties(typeof(T));
私有void GetProperties(类型classType)
{
foreach(classType.GetProperties(BindingFlags.Public | BindingFlags.Instance)中的PropertyInfo属性)
{
if(property.PropertyType.IsGenericType&&(property.PropertyType.GetGenericTypeDefinition()==typeof(IEnumerable)))
{
ValuesToList.Add(property.Name);
foreach(在property.PropertyType.GetGenericArguments()中键入nestedType)
{
GetProperties(nestedType);
}
}
}
}
私有列表值stolist{get;set;}

我相信我已经接近了,但如果能再看一眼,我会很感激的。

这不起作用的原因是您提到的属性不是
公共的,并且您没有设置
绑定标志。非公共的
绑定标志

因此,使其工作的一种方法是将它们设置为
public

public class ItemData
{
    public long ItemId { get; set; }
    public bool Active { get; set; }

    public IEnumerable<ItemAttribute> ItemAttributes { get; set; }
    public IEnumerable<string> ItemUrls { get; set; }
    public IEnumerable<InventoryInformation> InventoryInformation { get; set; }
}

或者添加
| | BindingFlags.NonPublic
@ErikPhilips IMO,这应该是一个单独的答案(我会投票!)-它在原始上下文中更正确地解决了这个问题,我感觉很抱歉,我已经更新了答案以包括这一点。它确实比更改类成员的范围更有意义。:)@MarcGravell是的,对于这样一个简单的问题,我不介意在Rufus的回答中结合它们。
private static void GetProperties(Type classType)
{
    foreach (PropertyInfo property in classType.GetProperties(
        BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic))
    {
        // other code omitted...