2010-04-15 11 views
5
sTypeName = ... //do some string stuff here to get the name of the type 

/* 
The Assembly.CreateInstance function returns a type 
of System.object. I want to type cast it to 
the type whose name is sTypeName. 

assembly.CreateInstance(sTypeName) 

So, in effect I want to do something like: 

*/ 

assembly.CreateInstance(sTypeName) as Type.GetType(sTypeName); 

Come si fa? E, cosa prendo sul lato sinistro dell'espressione di assegnazione, supponendo che questo sia C# 2.0. Non ho la parola chiave var.Tipizzato a un tipo solo dalla rappresentazione di stringa del nome del tipo

risposta

2

Di solito si lasciano tutte le classi, si desidera creare un'istanza di questo in modo dinamico, implementare un'interfaccia comune, diciamo IMyInterface. È possibile creare un'istanza dalla stringa nomeclasse in questo modo:

Assembly asm = Assembly.GetExecutingAssembly(); 
string classname = "MyNamespace.MyClass"; 
Type classtype = asm.GetType(classname); 

// Constructor without parameters 
IMyInterface instance = (IMyInterface)Activator.CreateInstance(classtype); 

// With parameters (eg. first: string, second: int): 
IMyInterface instance = (IMyInterface)Activator.CreateInstance(classtype, 
         new object[]{ 
          (object)"param1", 
          (object)5 
         }); 

Anche se non avete un'interfaccia comune, ma conoscere il nome del metodo (come stringa) è possibile richiamare i vostri metodi come questo (molto simile per proprietà, eventi e così via):

object instance = Activator.CreateInstance(classtype); 

int result = (int)classtype.GetMethod("TwoTimes").Invoke(instance, 
         new object[] { 15 }); 
// result = 30 

La classe esempio:

namespace MyNamespace 
{ 
    public class MyClass 
    { 
     public MyClass(string s, int i) { } 

     public int TwoTimes(int i) 
     { 
      return i * 2; 
     } 
    } 
} 
2

Sfortunatamente non c'è modo in .NET di fare quello che vuoi.

possibili soluzioni parziali sono:

  1. Se si conosce il tipo al momento della compilazione (improbabile, dal momento che si sta creando è in fase di esecuzione da una stringa) poi semplicemente gettato a quel tipo:

    YourType t = (YourType)Activator.CreateInstance(sTypeName); 
    
  2. Se si sa che tutti i possibili tipi attueranno una specifica, un'interfaccia comune allora si può lanciare a tale interfaccia, invece:

    IYourInterface i = (IYourInterface)Activator.CreateInstance(sTypeName); 
    

Se non riesci a eseguire una di queste operazioni, sfortunatamente, sei bloccato con object e riflessione.

+0

Grazie, avevo già fatto (2) e stavo cercando le opzioni. –

2

.

Definire un metodo generico nella classe, e poi si può lanciare in questo modo:

public T Cast<T>(object obj) 
{ 
     return (T) obj; 
} 

string sTypename = "SomeClassName"; 
MethodInfo cast = this.GetType().GetMethod("Cast"); 
MethodInfo genericCast = cast.MakeGenericMethod(new Type[] { Type.GetType(sTypename) }); 
Object castedValue = genericCast.Invoke(this, new object[] { instanceToBeCasted }); 

Ma poi penso, qual è il punto di tale fusione, se non è possibile memorizzare il valore fuso in una variabile di il tipo effettivo, proprio perché non si conosce il tipo effettivo al momento della scrittura del codice?

Problemi correlati