2009-12-21 12 views
5

es posible llamar a un método de reflexión con "explict type argument" <S> definición
p. oObject.Cast<S>()?Cómo llamar a un método genérico a través de la reflexión

donde es:

IList <P> oObject = new List <P>(); 

he intentado con

oObject.getType().InvokeMember("Cast", BindingFlags.InvokeMethod, null, oObject, null) 

pero no funciona, ¿alguien sabe por qué?


Aquí está el código de prueba completa, pero todavía no funciona. La última línea produce siempre excepción. ¿Es posible hacer que funcione?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Reflection; 

namespace reflection_tester 
{ 
    class CBase 
    { 
     public string Ja = "I am the base"; 
    } 

    class MyClass01 : CBase 
    { 
     public string _ID; 

     public string ID 
     { 
      get { return _ID; } 
      set { _ID = value; } 
     } 
    } 

    class Program 
    { 

     public static object wrapper() 
     { 
      //return a list of classes MyClass01 

      IList<MyClass01> lstClass01 = new List<MyClass01>(); 

      MyClass01 oClass01a = new MyClass01(); 
      oClass01a.ID = "1"; 

      MyClass01 oClass01b = new MyClass01(); 
      oClass01b.ID = "2"; 

      lstClass01.Add(oClass01a); 
      lstClass01.Add(oClass01b); 

      return lstClass01; 
     } 

     static void Main(string[] args) 
     { 

      MyClass01 oMy1 = new MyClass01(); 
      oMy1._ID = "1"; 

      MyClass01 oMy2 = new MyClass01(); 
      oMy2._ID = "3"; 

      IList<MyClass01> oListType01 = new List<MyClass01>(); 

      oListType01.Add(oMy1); 
      oListType01.Add(oMy2); 

      object oObjectType = new object(); 

      oObjectType = oListType01; 

      /* this works */ 
      IEnumerable<CBase> enumList = oListType01.Cast<CBase>(); 

      MethodInfo mInfo = typeof(System.Linq.Enumerable).GetMethod("Cast", new[] { typeof(System.Collections.IEnumerable) }).MakeGenericMethod(typeof(CBase)); 

      /* this does not work, why ? throws exception */ 
      IEnumerable<CBase> enumThroughObject = (IEnumerable<CBase>)mInfo.Invoke(oObjectType, null); 

      return; 
     } 
    } 
} 

Respuesta

13

El método de extensión moldeada vive en la clase Enumerable, y hay que llamar MakeGenericMethod:

typeof(System.Linq.Enumerable) 
    .GetMethod("Cast", new []{typeof(System.Collections.IEnumerable)}) 
    .MakeGenericMethod(typeof(S)) 
    .Invoke(null, new object[] { oObjectType }) 

actualización: Dado que el método es estático, el primer parámetro para Invocar debe ser null

+0

La función de invocación no toma un parámetro, así que si pongo el segundo parámetro como "nulo" recibo una excepción. alguna pista por qué? – milan

+0

La obtención de excepciones es: Número de parámetros no válido. – milan

+0

'Enumerable.Cast ()' no toma ningún "argumento". El argumento presentado en este caso es el objeto al que desea llamar el método de extensión Ejecutar. – user7116

0

creo que estás buscando Type.MakeGenericType

+2

Lo siento pero no entiendo d tal breve explicación, ¿podría escribir algún código para entenderlo mejor? – milan

Cuestiones relacionadas