所以,我需要调用第三方方法,它有一个像这样的签名
ThirdPartyMethod<T>(IEnumerable<T> items)
我的问题是我在编译时不知道对象的类型。
在编译时我有这个
IEnumerable myObject;
Type typeOfEnumerableIHave;
Sooo..can能以某种方式帮助我吗?
为简单起见,假装我有这样的方法
void DoWork(IEnumerable items, Type type)
{
//In here I have to call ThirdPartyMethod<T>(IEnumerable<T> items);
}
答案 0 :(得分:5)
由于您拥有IEnumerable myObject;
和ThirdPartyMethod<T>(IEnumerable<T> items)
之类的签名,因此您可以使用Cast()
:
ThirdPartyMethod(myObject.Cast<T>())
如果您在编译时不知道T
类型,则应在运行时提供它。
考虑您第三方库看起来像这样
public static class External
{
public static void ThirdPartyMethod<T>(IEnumerable<T> items)
{
Console.WriteLine(typeof(T).Name);
}
}
如果你有以下
Type theType = typeof(int);
IEnumerable myObject = new object[0];
您可以在运行时
获取通用方法ThirdPartyMethod
和Cast
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 });
最后你调用方法:
targetGenericMethod.Invoke(null, new object[] { caxtGenericMethod.Invoke(null, new object[] { myObject }) });
答案 1 :(得分:2)
您可以尝试这样的事情:
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});
}
代码创建泛型类型的列表实例&#34; type&#34; (通过使用MakeGenericType)。然后将您的item元素复制到列表中,并通过relection调用第三方方法(注意&#34; MakeGenericMethod&#34;调用以确保该方法与方法参数具有相同的类型参数。