2009-06-09 16 views
5

Sto provando a creare un'istanza di una classe generica, senza sapere quale tipo eseguirne il cast fino al runtime. Ho scritto il seguente codiceC# Generics

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

Speriamo che ti dà un idea di quello che sto cercando di fare, ma non ci vorrà compilare si dice solo

"del tipo o dello spazio dei nomi PTYPE non è stato trovato" .

C'è un modo semplice per farlo?

Grazie

Gavin

risposta

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

Tuttavia, a meno che non si esegue il cast a un'interfaccia non generica (IComparer, forse), si perde la possibilità di usarlo come un tipo generico.


La risposta più comune è una classe di base non generico/Interfaccia:

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

È quindi possibile richiamare tramite il non generico ISomeInterface senza dover passare tramite qualunque cerchi in più.

Esempio con MakeGenericMethod qui sotto - ma un'interfaccia di base non generico sarebbe più efficiente:

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

Ho ragione nel pensare che il codice mi fornisca un'istanza della classe come oggetto? Se sì, come posso quindi lanciarlo sul tipo della classe in modo da poter chiamare i suoi metodi? Grazie – Gavin

+0

Non è possibile (in modo convenzio- nale) - da qui il mio commento riguardo forse al casting in un tipo non generico (forse mettete i vostri metodi lì?). Potresti forse chiamare in un metodo generico ** e fare il lavoro lì? (Aggiungerò un esempio). –

1

Qualcosa di simile a questo:

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

object o = Activator.CreateInstance (toConstruct); 

Sembra che io sono a rallentare.