2014-10-28 3 views
0

Итак, мне нужно вызвать метод третьей стороны, которая имеет подпись, как этотКастинг IEnumerable к IEnumerable <T> с отражением

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

В каком контексте у вас есть это 'IEnumerable myObject;'? Не могли бы вы показать немного больше вашего кода? – BrunoLM

+0

@BrunoLM Я добавил немного больше, я не уверен, что это поможет или нет –

ответ

4

Поскольку у вас есть 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 }) }); 
+0

Я не знаю, как правильно это сказать , но у меня нет доступа к '' '', у меня есть только '' Type'' ..if, который имеет смысл –

+0

@KyleGobel расширил мой ответ, чтобы показать, как динамически разрешать общий метод. –

+0

awesome, спасибо, даже не передумал называть метод третьей стороны с таким отражением –

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

код создает экземпляр списка из «типа» универсального типа (с помощью MakeGenericType). Элементы вашего элемента затем копируются в список, а метод третьей стороны вызывается посредством преобразования (обратите внимание на вызов «MakeGenericMethod», чтобы гарантировать, что метод имеет тот же параметр типа, что и аргумент метода.