Comment puis-je utiliser une dynamique comme générique?
Ce p> et cette p> les deux produire cette erreur p> Que puis-je faire à x code> pour le rendre suffisamment légitime pour être utilisé dans
6 Réponses :
Vous ne pouvez pas. L'ensemble des génériques est la sécurité de la compilation, ce qui signifie qu'ils doivent être connus au moment de la compilation. Et tout le point de dynamique est que vous n'avez pas besoin de connaître le type exact au moment de la compilation et d'utiliser Dispatching d'exécution => C'est l'opposé absolument exact des génériques. Donc, ne perdez pas votre temps => Une fois que vous obtenez le chemin dynamique / réflexion, vous pouvez oublier les génériques et la sécurité de la compilation. Vous devrez marcher sur ce chemin jusqu'à la fin. P>
afin de répondre à votre question: p>
Que puis-je faire à X pour le rendre suffisamment légitime d'être utilisé? P> blockQuote>
La seule chose que vous puissiez faire est d'utiliser un type connu au moment de la compilation, sinon vous ne pouvez pas utiliser de génériques. P>
Eh bien, vous pouvez utiliser des génériques avec un type qui n'est pas connu à l'heure de la compilation, voir ma réponse.
Vous obtenez cette erreur car En fait, vous peut utiliser em> utiliser x code> n'est pas un type. Vous devez spécifier un type comme paramètre type em>.
dynamique code> comme paramètre de type si vous l'utilisez si vous l'utilisez. Correctement: p>
var dict = new Dictionary<string, dynamic>();
dict.Add("Item1", 123);
dict.Add("Item2", "Blah");
Le moyen le plus rapide de rendre ce travail est de rendre votre type anonyme de type un vrai type.
donc au lieu de p> vous devez faire p> < Pré> xxx pré> p>
Notez que x code> est toujours fortement saisi dans le premier extrait de code; Cependant, le type est anonyme.
Il est difficile de dire ce que vous essayez exactement de faire. Mais si vous souhaitez appeler une méthode générique avec un paramètre de type identique à celui de certains objets, vous ne pouvez pas le faire directement. Mais vous pouvez écrire une autre méthode qui prend votre objet en tant que paramètre, laissez le type code> dynamique appelez ensuite la méthode souhaitée:
void HelperMethod<T>(T obj) { CallFunction<T>(); } ⦠dynamic x = â¦; HelperMethod(x);
Wow .. c'est génial .. une différence subtile est que lorsque x code> est null, le mécanisme d'inférence de type échoue ici. Si
x code> est fortement typé, la méthode appelle elle-même échoue. Juste quelque chose à avoir à l'esprit ..
Vous pouvez utiliser l'inférence de type pour trampoline l'appel: Ceci déterminera l'argument de type au moment de l'exécution en fonction du type d'exécution de la valeur de Notez que la différence de Darin, je crois que ce est em> une technique utile - dans les mêmes situations Où pré-dynamique vous finiriez par appeler la méthode générique avec une réflexion. Vous pouvez faire de cette partie une partie em> de la dynamique de code, mais gardez le le reste em> du code (du type générique sur le verso) de type-coffre-fort. Il permet un em> étape pour être dynamique - juste le seul bit où vous ne connaissez pas le type. P> p> x CODE>, en utilisant le même type d'inférence de type, il utiliserait si
x code> avait ceci comme type em> type de compilation em>. Le paramètre est seulement em> présent pour effectuer le travail d'inférence de type. P>
Hah! Cela fonctionne bien avec une petite adaptation. Génie pur. Je l'aime. Le problème est que, avec votre définition actuelle, il doit s'agir d'un type de référence pour l'utiliser comme paramètre plus tard dans le fichier code>. Pour améliorer ce problème, j'ai fait ces modifications:
Vidéos statique ApplinfunctionWithInference
Statique Void CallfunctionWithInference
@Travisj: Est-ce parce que Callfunction code> a-t-il une contrainte? Vous ne nous avez pas dit que dans la question :) Sans la contrainte sur
Callfunction code> Ça devrait être bien.
Oui, désolé pour l'omission :) La contrainte dans Callfunction code> est une initialisation (la ligne) d'un fichier DBSet EF sous la forme de
this.dbset = context.set
Le premier commentaire devrait lire "le problème sur ma fin b> est-ce ..."
@Travisj: Righto - ça a du sens :)
J'ai prêté cette réponse à cause de son génialité.
J'ai eu un comportement étrange en utilisant cela lorsque vous essayez de faire x code> avec
activator.createInstance code>. J'ai eu des difficultés pendant quelques jours avec elle et j'espérais que vous puissiez donner une idée? Je reçois une exception: exception:
Référence d'objet non définie sur une instance d'un objet. CODE> INTERNET:
Microsoft.cshaarp.runtimeBinder.symboltable.getoriginalTypepa RAMETType (type T) +10 code>. Voici le code:
dynamique anyobject = activator.createinstance ("myassemblage", "myassembly.models.dbmodels." + Enttitytype) .unwrap (); CallWithInference (AnyObject); Code> Qu'est-ce que j'ai mal fait?
@Travisj: Je pense que cela aiderait si vous pouviez créer une nouvelle question pour cela, avec un programme court mais complet i> démontrant le problème.
J'ai fait un exemple complet, mais était incapable de reproduire exactement le problème. La question est ici: Stackoverflow.com/q/12096695/1026459
Vous devriez pouvoir appeler la fonction comme celle-ci si votre fonction est définie comme p> Vous pouvez simplement l'appeler avec p> c # est capable de déduire des paramètres de type générique dans de nombreuses situations. P> P>
Votre code est déroutant. On dirait que vous essayez de passer une variable comme paramètre de type? Cela ne fonctionnera de toute façon. Il doit être un type.
@ M.Babcock - Même lors de la convertie en un type, la même erreur est émise. Par exemple:
type T; t = légitimeObject.getType (); Callfunction (); code> produit la même erreur.
Non non un type comme dans
System.type code> Un type comme dans
String code> ou
int code> directement. Les variables ne peuvent pas être utilisées comme paramètres de type.
var x code> ne signifie pas que la variable
x code> n'est pas fortement typée. Le compilateur déduit (suppose si vous préférez) le type de l'expression à droite de
= code> et en fait le type de
x code>. Si le compilateur pense que l'expression est de type
chaîne code> alors
var x code> signifie exactement la même chose que
chaîne x code>. Notez également que cela se produit à l'heure de la compilation, pas à l'exécution!
Vous n'avez pas de sens: Considérez votre code si x était i> fortement typé:
string x = "x"; code>. Vous n'appelez pas
composerfonction () code> ou
composé () code>; Vous appelez
composerfonction () code> Cela n'a pas de sens, sauf si CallFunction ait un paramètre de chaîne ou une valeur de retour; Un appel plus probable serait
string x = appelfunction (); code> ou
composerfonction (x) code>. Pouvez-vous donner un exemple de la fonction que vous souhaitez appeler? Qu'essayez-vous d'atteindre?
@Phoog - Il n'y a pas d'essai;) J'ai réussi à y parvenir avec l'aide immaculée de Jonskeet. Voir sa réponse et les commentaires ci-dessous pour un meilleur contexte.
Remplir un contrôle de liste semblait un bon cas d'utilisation pour cela