2010-04-15 5 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); 

Comment faire? Et, que dois-je prendre sur le côté gauche de l'expression d'affectation, en supposant que c'est C# 2.0. Je n'ai pas le mot-clé var.Typecast à un type de seulement la représentation sous forme de chaîne du nom de type

Répondre

2

Habituellement, vous laissez toutes les classes, vous voulez instancier cela dynamiquement, implémenter une interface commune, disons IMyInterface. Vous pouvez créer une instance de la chaîne de classname comme ceci:

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

Même si vous ne disposez pas d'une interface commune, mais le nom de la méthode (sous forme de chaîne), vous pouvez appeler vos méthodes comme celui-ci (très similaire pour propriétés, événements, etc.):

object instance = Activator.CreateInstance(classtype); 

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

La classe exemple:

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

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

Malheureusement, il n'y a aucun moyen .NET pour faire ce que vous voulez.

solutions partielles sont possibles:

  1. Si vous connaissez le type à la compilation (peu probable, étant donné que vous créez au moment de l'exécution d'une chaîne) alors simplement jeter à ce type:

    YourType t = (YourType)Activator.CreateInstance(sTypeName); 
    
  2. Si vous savez que tous les types possibles mettront en œuvre une interface spécifique, commune, vous pouvez jeter à cette interface à la place:

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

Si vous ne pouvez pas faire l'une des choses ci-dessus, malheureusement, vous êtes coincé avec object et de réflexion.

+0

Merci, j'avais déjà fait (2) et je cherchais des options. –

2

.

définir une méthode générique dans votre classe, puis vous pouvez jeter comme ceci:

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

Mais je pense, quel est le point de cette coulée si vous ne pouvez pas stocker la valeur casted dans une variable le type réel, précisément parce que vous ne connaissez pas le type réel au moment de l'écriture du code?