2009-06-09 19 views
5

Estoy tratando de crear una instancia de una clase genérica, sin saber qué tipo para lanzarlo hasta el tiempo de ejecución. He escrito el siguiente códigoC# Generics

 Type pType = propertyInfo.GetType(); 
     ObjectComparer<pType> oc = new ObjectComparer<pType>(); 

suerte que le da una idea de lo que estoy tratando de hacer, sin embargo no lo puedo compilar sólo dice

"el tipo o espacio pType no se pudo encontrar" .

¿Hay alguna manera fácil de hacer esto?

Gracias

Gavin

Respuesta

10
Type type = typeof(ObjectComparer<>).MakeGenericType(pType); 
object obj = Activator.CreateInstance(type); 

Sin embargo, a menos que lances a una interfaz no genérico (IComparer, tal vez), se pierde la capacidad de utilizarla como un tipo genérico.


La respuesta más común aquí es una clase base no genérico/interfaz:

interface ISomeInterface { 
    object SomeMethod(object value); 
} 
interface ISomeInterface<T> : ISomeInterface { 
    T SomeMethod(T value); 
} 

A continuación, puede invocar a través de la no genérico ISomeInterface sin tener que saltar a través de aros ningún adicionales.

Ejemplo usando MakeGenericMethod abajo - pero una interfaz base no genérica haría más eficiente:

class Program { 
    static void Main() { 
     int i = 123; 
     typeof(Program).GetMethod("Foo", 
       BindingFlags.Static | BindingFlags.NonPublic) 
      .MakeGenericMethod(i.GetType()) 
      .Invoke(null, new object[] { i }); 
    } 
    static void Foo<T>(T value) { 
     ObjectComparer<T> comparer = new ObjectComparer<T>(); 
     comparer.Bar(value); 
    } 
} 
class ObjectComparer<T> { 
    public void Bar(T value) { 
     Console.WriteLine(typeof(T).Name + " = " + value); 
    } 
} 
+0

¿Estoy en lo cierto al pensar que el código me da una instancia de la clase como un objeto? Si es así, ¿cómo podría convertirlo al tipo de clase para que pueda llamar a sus métodos? Gracias – Gavin

+0

No se puede (convenientemente) - de ahí mi comentario sobre tal vez el lanzamiento a un tipo no genérico (tal vez poner sus métodos allí?). ¿Podría llamar a un ** método ** genérico y hacer el trabajo allí? (Añadiré un ejemplo). –

1

Algo como esto:

Type someType = typeof(ObjectComparer<>); 
Type toConstruct = someType.MakeGenericType (pType); 

object o = Activator.CreateInstance (toConstruct); 

Parece que estoy a disminuir.