web-dev-qa-db-fra.com

Comment utiliser la variable locale comme type? Le compilateur dit "c'est une variable mais est utilisé comme un type"

Au moment de l'exécution, je ne sais pas quel type de variable v1 est. Pour cette raison, j'ai écrit de nombreux if else déclarations:

if (v1 is ShellProperty<int?>)
{
    v2 = (v1 as ShellProperty<int?>).Value;
}
else if (v1 is ShellProperty<uint?>)
{
    v2 = (v1 as ShellProperty<uint?>).Value;
}
else if (v1 is ShellProperty<string>)
{
    v2 = (v1 as ShellProperty<string>).Value;
}
else if (v1 is ShellProperty<object>)
{
    v2 = (v1 as ShellProperty<object>).Value;
}    

La seule différence réside dans ShellProperty<AnyType>.

Donc, au lieu d'écrire ceci avec beaucoup de if else instructions, j'ai décidé d'utiliser la réflexion pour obtenir le type de propriété au moment de l'exécution:

 Type t1 = v1.GetType().GetProperty("Value").PropertyType;
 dynamic v2 = (v1 as ShellProperty<t1>).Value;

Ce code obtient le PropertyType de v1 et l'assigne à la variable locale t1, mais après cela, mon compilateur dit que:

t1 est une variable mais est utilisée comme un type

Cela ne me permet donc pas d'écrire t1 à l'intérieur ShellProperty<>.

Veuillez me dire comment résoudre ce problème et comment obtenir un code plus compact que ce que j'ai. Dois-je créer une nouvelle classe?

16

Vous étiez très proche, il vous manquait juste un appel à MakeGenericType.

Je crois que votre code ressemblerait à ceci:

Type t1 = v1.GetType().GetProperty("Value").PropertyType;
var shellPropertyType = typeof(ShellProperty<>);
var specificShellPropertyType = shellPropertyType.MakeGenericType(t1);
dynamic v2 = specificShellPropertyType.GetProperty("Value").GetValue(v1, null);

Edit: Comme l'a souligné @PetSerAl, j'ai ajouté des couches d'indirection inutiles. Désolé OP, vous voulez probablement une doublure comme:

dynamic v2 = v1.GetType().GetProperty("Value").GetValue(v1, null);
16
Dex

Pour les génériques, vous devez les créer dynamiquement.

MethodInfo method = typeof(Sample).GetMethod("GenericMethod");
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(this, null);

Pour créer un objet générique, vous pouvez

var type = typeof(ShellProperty<>).MakeGenericType(typeof(SomeObject));
var v2 = Activator.CreateInstance(type);

Veuillez vous référer à Initialisation d'une variable générique à partir d'une variable de type C #

12
ProfFan