2010-03-06 4 views
0

J'ai une méthodeComment appeler dynamiquement une méthode générique basée sur un mappage dans un dictionnaire?

String Foo<T> where T: WebControl 

Maintenant, j'ai une chaîne comme « lien hypertexte ». Ce qui est vouloir appeler Foo<Hyperlink> basé sur un mappage de la chaîne au générique.

À quoi le dictionnaire doit-il ressembler?

Il n'est pas:

private Dictionary<string, Type> _mapping = new Dictionary<string, Type>() 
{ 
     {"hyperlink", typeof(HyperLink)} 
}; 

Je veux y accéder comme Foo<_mapping[mystring]> est-ce possible? Si oui, à quoi doit ressembler le dictionnaire?

Modifier: solution acceptée

String _typename = "hyperlink"; 
MethodInfo _mi = typeof(ParserBase).GetMethod("Foo"); 
Type _type = _mapping[_typename]; 
MethodInfo _mig = _mi.MakeGenericMethod(_type); 
return (String)_mig.Invoke(this, new object[] { _props }); // where _props is a dictionary defined elsewhere 
// note that the first parameter for invoke is "this", due to my method Foo is not static 
+0

J'expurgée mon poste. J'obtiens ce que vous essayez d'accomplir maintenant. Vous voulez appeler dynamiquement une fonction générique. – Thomas

+0

Merci quand même. J'ai édité le titre basé sur votre description ce que j'essayais de faire =) – citronas

Répondre

1

Ce que vous voulez est impossible, car ce serait l'exécution (par exemple le dictionnaire pourrait contenir quoi que ce soit plus tard). Si vous voulez le générer manuellement via runtime, vous pouvez le faire, mais vous n'obtiendrez pas la vérification de la compilation de C# sur les génériques. Vous pouvez le faire via MethodInfo.MakeGenericMethod.

Comme ceci:

var m = typeof(MyClass); 
var mi = ex.GetMethod("Foo"); 
var mig = mi.MakeGenericMethod(_mapping["hyperlink"]); 

//Invoke it 
mig .Invoke(null, args); 
+0

Ok alors, comment puis-je le générer via l'exécution? Je remplis ce dictionnaire manuellement, donc je sais quelle classe dérive de WebControl. – citronas

+0

@citronas - Je mets un exemple rapide pour faire une méthode générique, il y a un équivalent si vous avez besoin de la classe appelée MakeGenericType: http://msdn.microsoft.com/en-us/library/system.type.makegenerictype.aspx –

+0

Merci beaucoup, j'ai été capable de trouver une solution basée sur votre échantillon, bien que je n'ai presque aucune expérience avec relection =) J'ai simplifié ma solution et l'ai éditée dans ma question, afin que d'autres puissent bénéficier de ce fil. – citronas

1

Il est impossible de cette façon. Generics ne prend en charge que la liaison par compilation.

1

Non, vous ne pouvez pas faire cela. Votre type générique veut créer lui-même au moment de la compilation, mais il ne sait pas de quel type il s'agit jusqu'à l'exécution. Vous pouvez cependant utiliser la réflexion.

Type untypedGeneric = typeof(Foo<>); 
Type typedGeneric = untypedGeneric.MakeGenericType(_mapping[mystring]); 
Questions connexes