views:

415

answers:

5

I am trying out a little reflection and have a question on how the cast the result object to an IList.

Here is the reflection:

private void LoadBars(Type barType)
{
    // foo has a method that returns bars
    Type foo = typeof(Foo);

    MethodInfo method = foo.GetMethod("GetBars")
        .MakeGenericMethod(bar);

    object obj = method.Invoke(foo, new object[] { /* arguments here */ });
    // how can we cast obj to an IList<Type> - barType
}

How can we cast the result of method.Invoke to an IList of Type from the barType argument?

+5  A: 

The point of a cast is usually to tell the compiler that you have some extra information - that you know something at compile time. You don't know that information here - you only know it at execution time.

What would you expect to do with the value after casting it? Admittedly there are some times when it would be useful - when you've got to use a generic interface, even if you want to get at members which don't require the type parameter (e.g. Count in IList<T>). However, if that's not what you're trying to do it would really help if you could give more information.

Jon Skeet
We want to iterate the list as its casted type. Which I admit doesn't make any sense, we need to tell the compiler the type in order for it to generate what it needs. The goal of the question was to explore an edge case that is really a hack around a LOB irregularity. Thanks for clearly presenting the issue for me.
blu
A: 

In .NET 4.0 you can use expression trees to achive that.

bjornhol
A: 
private void LoadBars<T>()
{
    Type barType = typeof(T);
    // foo has a method that returns bars
    Type foo = typeof(Foo);

    MethodInfo method = foo.GetMethod("GetBars")
        .MakeGenericMethod(bar);

    IList<T> obj = (IList<T>)method.Invoke(foo, new object[] { /* arguments here */ });
}
Greg
Exactely, but now T has to be known at compile time.
Radu094
A: 

Casting would only make sense if the caller of your function new barType at compile time, and not a runtime. And once that is true, you could just template the function to:

private IList<T> LoadBars<T>()
{
...
return obj as IList<T>;
}
Radu094
A: 

I've just finished wrestling with this problem.
True, you cannot cast the object into a Generic IList but you can convert it into a strongly typed Array by invoking the "ToArray" method of the List object.

Solution pilfered from another blog. http://amazedsaint.blogspot.com/2008/04/creating-generic-list-at-runtime.html

ToArrayMethod = obj.GetType().GetMethod("ToArray");

System.Array stronglyTypedArray=(System.Array) ToArrayMethod.Invoke(obj,null);