reflection to invoke methods of unknown property types

I want to call the generic method, 'get_', for each property, IEnumerable<class>, of my view model class to avoid creating lengthy switch statements that explicitly get each list... Does anyone know how to get the object type and method generically?

    foreach (var prop in vm.GetType().GetProperties().Where(x => x.GetCustomAttributes<ExportAttribute>().Any()))
    {
        var objType = ??;
        var method = objType.GetMethod(<by name>);
        var list = method.Invoke(prop, null);
        foreach (var item in list)
        {
            //do something
        }
    }
Jon Skeet
people
quotationmark

I would use something like:

foreach (var prop in vm.GetType()
                       .GetProperties()
                       .Where(x => x.GetCustomAttributes<ExportAttribute>().Any()))
{
    var list = (IEnumerable) prop.GetValue(vm, null);
    foreach (var item in list)
    {
        // do something
    }
}

Now item will be typed as object... but you can't really do better than that anyway. Your "do something" code can't use any members of the element type anyway, because it could be any type.

If, on the other hand, you know that every property will be something implementing IEnumerable<T> where T will in each case have a common base type, then due to the generic covariance of IEnumerable<T> introduced in .NET 4, you can write:

foreach (var prop in vm.GetType()
                       .GetProperties()
                       .Where(x => x.GetCustomAttributes<ExportAttribute>().Any()))
{
    var list = (IEnumerable<BaseType>) prop.GetValue(vm, null);
    foreach (var item in list)
    {
        // do something
    }
}

Then you can access item.PropertyDeclaredInBaseType.

Note that I've changed the target of the call to vm instead of null, as presumably you want those instance properties...

people

See more on this question at Stackoverflow