Question

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 puis-je faire cela? Et, qu'est-ce que je prends sur le côté gauche de l'expression d'affectation, en supposant que cela est C # 2.0. Je n'ai pas le mot-clé var.

Était-ce utile?

La solution

En général, vous laissez toutes les classes, vous voulez instancier cette dynamique, mettre en œuvre une interface commune, permet IMyInterface de dire. 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 d'une interface commune, mais le nom de la méthode (sous forme de chaîne), vous pouvez appeler vos méthodes comme celle-ci (très similaires pour les propriétés, l'événement et ainsi de suite):

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

Autres conseils

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

solutions partielles possibles sont:

  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 vont mettre en œuvre un cadre précis, interface commune, alors vous pouvez jeter à cette interface à la place:

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

Si vous ne pouvez pas non plus de ce qui précède alors, malheureusement, vous êtes coincé avec object et de réflexion.

.

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 alors je pense, quel est le point de cette coulée si vous ne pouvez pas stocker la valeur casted dans une variable de la réelle type précisément parce que vous ne connaissez pas le type réel au moment d'écrire le code?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top