2009-12-21 4 views
5

è possibile chiamare con riflessione un metodo con "argomento tipo esplicativo" <S> definizione
ad es. oObject.Cast<S>()?Come chiamare un metodo generico tramite riflessione

dov'è:

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

ho provato con

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

ma non funziona, qualcuno sa perché?


Ecco il codice di prova completo, ma ancora non funziona. L'ultima riga produce sempre un'eccezione. È possibile farlo funzionare?

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

risposta

13

Il metodo di estensione Fusioni vive sulla classe Enumerable, ed è necessario chiamare MakeGenericMethod:

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

aggiornamento: Poiché il metodo è statico, il primo parametro su Invoke dovrebbe essere null

+0

La funzione Invoke non accetta un parametro, quindi se inserisco il secondo parametro come "null" ottengo un'eccezione. qualche indizio perché? – milan

+0

L'ottenimento di eccezioni è: Numero di parametri non valido. – milan

+0

'Enumerable.Cast ()' non accetta alcun "argomento". L'argomento indicato in questo caso è l'oggetto che si desidera chiamare il metodo di estensione Cast. – user7116

0

Penso che tu sia alla ricerca di Type.MakeGenericType

+2

Mi dispiace ma non lo so. d una spiegazione così breve, potresti scrivere qualche codice per comprenderlo meglio? – milan