2008-11-19 25 views
22

Si es más difícil de explicar con palabras, vamos a ver un ejemplo tengo una función genérica como esta¿Cómo se usa typeof o GetType() como plantilla genérica?

void FunctionA<T>() where T : Form, new() 
{ 
} 

Si tengo un tipo reflejada, ¿cómo se utiliza con la función anterior? Tengo ganas de hacer esto

Type a = Type.GetType("System.Windows.Forms.Form"); 
FunctionA<a>(); 

De causa que el método anterior no funciona.

Respuesta

11

No puede. Los genéricos en .NET deben resolverse en tiempo de compilación. Intentas hacer algo que los resuelva en tiempo de ejecución.

Lo único que puede hacer es proporcionar una sobrecarga para la función A que toma un objeto de tipo.


Hmmm ... es un idiota, pero tiene razón.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var t = typeof(Foo); 
     var m = t.GetMethod("Bar"); 
     var hurr = m.MakeGenericMethod(typeof(string)); 
     var foo = new Foo(); 
     hurr.Invoke(foo, new string[]{"lol"}); 
     Console.ReadLine(); 
    } 
} 

public class Foo 
{ 
    public void Bar<T>(T instance) 
    { 
     Console.WriteLine("called " + instance); 
    } 
} 

MakeGenericMethod.

+0

¿Cómo puede .NET estar tan cerca de el poder de una tecnología de 1958 y aún así estar tan lejos? –

+0

.NET es convencional, Lisp (supongo que es lo que su referencia es) no lo es. Eso puede responder la pregunta "por qué". –

+9

Esa es una respuesta muy definitiva. Lástima que sea incorrecto. Puede, a través de la reflexión, invocar métodos genéricos utilizando argumentos genéricos resueltos en tiempo de ejecución. No siempre es deseable, y uno puede preguntarse por qué tiene que hacerlo antes de usarlo realmente, pero es posible. –

9
class Program 
{ 
    static void Main(string[] args) 
    { 
     int s = 38; 


     var t = typeof(Foo); 
     var m = t.GetMethod("Bar"); 
     var g = m.MakeGenericMethod(s.GetType()); 
     var foo = new Foo(); 
     g.Invoke(foo, null); 
     Console.ReadLine(); 
    } 
} 

public class Foo 
{ 
    public void Bar<T>() 
    { 
     Console.WriteLine(typeof(T).ToString()); 
    } 
} 

funciona dynamicaly y s puede ser de cualquier tipo

6

Unos pocos años de retraso y de un blog de MSDN, pero esto podría ayudar:

Type t = typeof(Customer); 
IList lst = (IList)Activator.CreateInstance((typeof(List<>).MakeGenericType(t))); 
Console.WriteLine(lst.GetType().FullName); 
Cuestiones relacionadas