Luca Petrini
Luca Petrini

Reputation: 1745

Ignore collection properties in PropertyInfo

I have a function with this code:

foreach (PropertyInfo propertyInfo in typeof(T).GetProperties()){
//SOME CODE
if (propertyInfo.CanWrite)
    propertyInfo.SetValue(myCopy, propertyInfo.GetValue(obj, null), null);
}

I would avoid to check "collection" properties; to do this now I have insert this control:

 if (propertyInfo.PropertyType.Name.Contains("List")
     || propertyInfo.PropertyType.Name.Contains("Enumerable")
     || propertyInfo.PropertyType.Name.Contains("Collection"))
     continue;

but, It don't like me!

Which is a better way to do it?

Upvotes: 10

Views: 7899

Answers (3)

MaLio
MaLio

Reputation: 2540

bool isCollection = typeof(System.Collections.IEnumerable)
                          .IsAssignableFrom(propertyInfo.PropertyType);

Upvotes: 5

LukeH
LukeH

Reputation: 269678

I would probably check against IEnumerable.

if ((typeof(string) != propertyInfo.PropertyType) 
    && typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType))
{
    continue;
}

Upvotes: 9

Anthony Pegram
Anthony Pegram

Reputation: 126992

I was thinking you might want to check the interfaces the type of the property implements. (Removed redundant interfaces, as IList inherits ICollection and ICollection inherits IEnumerable.)

static void DoSomething<T>()
{
    List<Type> collections = new List<Type>() { typeof(IEnumerable<>), typeof(IEnumerable) };

    foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
    {
        if (propertyInfo.PropertyType != typeof(string) && propertyInfo.PropertyType.GetInterfaces().Any(i => collections.Any(c => i == c)))
        {
            continue;
        }

        Console.WriteLine(propertyInfo.Name);
    }
}

I added code to not reject string, as it implements IEnumerable, as well, and I figured you might want to keep those around.

In light of the redundancy of the prior list of collection interfaces, it may be simpler just to write the code like this

static void DoSomething<T>()
{
    foreach (PropertyInfo propertyInfo in typeof(T).GetProperties())
    {
        if (propertyInfo.PropertyType != typeof(string)
            && propertyInfo.PropertyType.GetInterface(typeof(IEnumerable).Name) != null
            && propertyInfo.PropertyType.GetInterface(typeof(IEnumerable<>).Name) != null)
        {
            continue;
        }

        Console.WriteLine(propertyInfo.Name);
    }
}

Upvotes: 17

Related Questions