使用反射</t>将IEnumerable转换为IEnumerable <t>

时间:2014-10-28 01:03:34

标签: c# reflection ienumerable

所以,我需要调用第三方方法,它有一个像这样的签名

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);
}

2 个答案:

答案 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];

您可以在运行时

获取通用方法ThirdPartyMethodCast
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;调用以确保该方法与方法参数具有相同的类型参数。