2011-02-10 5 views
1

Quelqu'un peut-il nous expliquer comment le faire fonctionner? Je passe dans le nom du type, et "t" est correctement rempli. Je ne peux pas comprendre comment lancer objectToCast pour taper "t". Toute aide est appréciée.Comment transtyper un type en C#

.... 
Type t = Type.GetType("castToTypeNameHere"); 
o = CastTo<t>(objectToCast); 
.... 

private T CastTo<T>(Object obj) 
{ 
    return (T)obj; 
} 

Pour votre information, voici la réponse que je trouve:

Type t = Type.GetType(element.Attribute("castToType").Value); 
MethodInfo castMethod = this.GetType().GetMethod("CastTo", BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod(t); 
object castedObject = castMethod.Invoke(this, new object[] { objectToCast }); 
+1

Pourriez-vous expliquer pourquoi vous voulez faire 'o = CastTo (obj);' quand vous pouvez simplement utiliser 'o = (t) obj;' s'il vous plaît? –

+0

@Kieren: Vous ne pouvez pas utiliser 'CastTo (obj)' ou '(t) obj' dans l'exemple donné car' t' est une instance 'Type', pas un nom de type. – LukeH

+0

@Kieren, vous ne pouvez pas faire ni '(t) obj;' ni 'CastTo ', d'où la question. –

Répondre

7

Lorsque vous utilisez des médicaments génériques (sans réflexion), les paramètres de type doivent être le nom des types, pas les instances de System.Type. Donc, vous ne pouvez pas dire

Type t = Type.GetType("castToTypeNameHere"); 
o = CastTo<t>(objectToCast); 

parce t n'est pas le nom d'un type. Il est comme si vous aviez dit

o = CastTo<typeof(int)>(objectToCast); 

au lieu de

o = CastTo<int>(objectToCast); 

Le premier est illégal, ce dernier est légal.

Je ne comprends pas ce que vous essayez d'atteindre. Si vous ne connaissez pas le type au moment de la compilation, une distribution comme celle-ci est inutile. Le compilateur ne connaîtra pas le type de o, et vous n'obtiendrez aucune des fonctions de sécurité de type au moment de la compilation ni d'IntelliSense.

1

Vous ne pouvez pas utiliser une variable pour un paramètre de type générique (par exemple, CastTo<t>) - il doit s'agir du nom de type réel (e.g., CastTo<string>).

0

Peut-être que Convert.ChangeType vous aiderait ici.

Type t = Type.GetType("castToTypeNameHere"); 

//using dynamic 
dynamic obj = Convert.ChangeType(objectToCast, t); 
obj.SomeExpectedMethod(); 

//casting to known interface 
var obj = Convert.ChangeType(objectToCast, t) as IKnowWhatImSupposedToBe; 
if (obj == null) HandleBadState(); 
0

Si vous pensez que la réponse que vous avez dit que vous avez trouvé:

Type t = Type.GetType(element.Attribute("castToType").Value); 
MethodInfo castMethod = this.GetType().GetMethod("CastTo", BindingFlags.Instance | BindingFlags.NonPublic).MakeGenericMethod(t); 
object castedObject = castMethod.Invoke(this, new object[] { objectToCast }); 

ne fait quelque chose, alors vous ne comprenez pas ce que signifie la coulée.

Le type de temps de compilation est toujours object, donc vous n'avez rien gagné. Vous pouvez directement lancer n'importe quoi comme object directement.

La conversion ne change pas le type d'un objet, elle indique seulement au compilateur que vous savez de quel type il s'agit et que le compilateur vous croira. Si vous avez tort, une erreur se produira encore, seulement au moment de l'exécution avec un InvalidCastException au lieu de la compilation.

Le problème est que le transtypage vers un type qui n'est pas connu au moment de la compilation n'a tout simplement aucun sens. Même si vous pouviez hypothétiquement, qu'est-ce que cela vous donnerait?

Type someType = Type.GetType("castToTypeNameHere"); 
someType o = CastTo<someType>(objectToCast); 

Quelles sont les méthodes o ont? someType pourrait être quelque chose, donc il n'y a aucun moyen le compilateur peut savoir quelles méthodes ou des propriétés qu'il a, ce serait exactement la même chose que

object o = (object)objectToCast

Parce qu'il n'y a rien que vous pourriez faire avec someType que vous ne pouviez pas avec object.

Questions connexes