Chase Florell
Chase Florell

Reputation: 47417

How to figure out if a Property is a List<T> where T is of custom Type?

I've got two models

public class Foo{
    public List<Bar> Bars {get; set;}
}
public class Bar{
    public string Name {get; set;}
}  

Then I have another method that looks something like this.

DoStuff<Foo, Bar>();
public void DoStuff<TModel, TCollection>(){

    foreach(var property in typeof(TModel).GetProperties())
    {
        if ( property.PropertyType.IsAssignableFrom(TCollection) )
        {
            // this is the property we need...
        }
    }
}

The above code is not working. How do I figure out if the property within the Model is a List of TCollection?

Upvotes: 1

Views: 196

Answers (2)

Lawrence
Lawrence

Reputation: 3297

Does something like this help?

foreach (var propertyInfo in typeof (Foo).GetProperties())
{
    if (propertyInfo.PropertyType.IsGenericType)
    {
        var isAList = propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof (List<>);
        var isGenericOfTypeBar = propertyInfo.PropertyType.GetGenericArguments()[0] == typeof(Bar);
    }
}

Upvotes: 1

Marc Gravell
Marc Gravell

Reputation: 1064064

It depends on what scenarios you want to cater for. At the most basic, you could check for IsGenericType and GetGenericTypeDefinition()==typeof(List<>). However! That fails a few cases, in particular custom subclasses, etc. The approach that much of the BCL takes is "is it an IList (non-generic) and does it have a non-object indexer?"; i.e.

static Type GetListType(Type type)
{
    if (type == null) return null;

    if (!typeof(IList).IsAssignableFrom(type)) return null;

    var indexer = type.GetProperty("Item", new[] { typeof(int) });
    if (indexer == null || indexer.PropertyType == typeof(object)) return null;

    return indexer.PropertyType;
}

with:

public void DoStuff<TModel, TCollection>()
{
    foreach (var property in typeof(TModel).GetProperties())
    {
        var itemType = GetListType(property.PropertyType);
        if(itemType == typeof(TCollection))
        {
            // this is the property we need
        }
    }
}

Upvotes: 1

Related Questions