So, I need to call a third party method, that has a signature like this
ThirdPartyMethod<T>(IEnumerable<T> items)
My problem is I don't know the type of my object at compile time.
At compile time I have this
IEnumerable myObject;
Type typeOfEnumerableIHave;
Sooo..can reflection help me out here somehow?
for simplicity sake, pretend I have a method like this
void DoWork(IEnumerable items, Type type)
{
//In here I have to call ThirdPartyMethod<T>(IEnumerable<T> items);
}
Since you have IEnumerable myObject;
and signature like ThirdPartyMethod<T>(IEnumerable<T> items)
you are able to use Cast()
:
ThirdPartyMethod(myObject.Cast<T>())
If you don't know the T
type at the compile time you should provide it at runtime.
Consider you third-party library looks like this
public static class External
{
public static void ThirdPartyMethod<T>(IEnumerable<T> items)
{
Console.WriteLine(typeof(T).Name);
}
}
if you have following
Type theType = typeof(int);
IEnumerable myObject = new object[0];
you can get generic methods ThirdPartyMethod
and Cast
at the runtime
var targetMethod = typeof(External).GetMethod("ThirdPartyMethod", BindingFlags.Static | BindingFlags.Public);
var targetGenericMethod = targetMethod.MakeGenericMethod(new Type[] { theType });
var castMethod = typeof(Enumerable).GetMethod("Cast", BindingFlags.Static | BindingFlags.Public);
var caxtGenericMethod = castMethod.MakeGenericMethod(new Type[] { theType });
Finally you call the method:
targetGenericMethod.Invoke(null, new object[] { caxtGenericMethod.Invoke(null, new object[] { myObject }) });
You could try something like this:
void DoWork(IEnumerable items, Type type)
{
// instance of object you want to call
var thirdPartyObject = new ThirdPartyObject();
// create a list with type "type"
var typeOfList = typeof(List<>).MakeGenericType(type);
// create an instance of the list and set items
// as constructor parameter
var listInstance = Activator.CreateInstance(listOfTypes, items);
// call the 3. party method via reflection, make it generic and
// provide our list instance as parameter
thirdPartyObject.GetType().GetMethod("ThirdPartyMethod")
.MakeGenericMethod(type)
.Invoke(thirdPartyObject, new []{listInstance});
}
The code creates a list instance of the generic type "type" (by using MakeGenericType). Your item elements are then copied to the list and the third party method is called via relection (note the "MakeGenericMethod" call to ensure that the method has the same type parameter as the method argument.