简体   繁体   中英

Reflection Property Names using Generic Types

I am having trouble getting all of the correct values in my reflection method. It seems when I start to transverse through the models that the method just stops finding the IEnumerables to transverse when it gets to the ItemData class. (ie It will only iterate through ItemId and Active but will not recognize the IEnumerables as properties)

What I need it to do is get the names of the various IEnumerables throughout the type. For example, when the type is passed through the code, the following items will be added to a list: Content, Data, ItemAttributes, ItemUrls, and InventoryInformation.

The Models:

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

The Code:

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

I believe I have got it close but another pair of eyes would be appreciated.

The reason this is not working is because the properties you mentioned are not public , and you do not have the BindingFlags.NonPublic binding flag set.

One way to get this to work, then, is to set them to 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; }
}

Alternatively, you can add BindingFlags.NonPublic to your binding flags:

private static void GetProperties(Type classType)
{
    foreach (PropertyInfo property in classType.GetProperties(
        BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic))
    {
        // other code omitted...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM