Pouvez-vous créer un délégué d'une méthode d'instance sans spécifier l'instance au moment de la création? En d'autres termes, pouvez-vous créer un délégué "statique" qui prend telle première paramètre l'instance que la méthode doit être appelée?
Par exemple, comment construire le délégué suivant à l'aide de la réflexion? P>
var func37 = (Func<CultureInfo,string>)(37.ToString); var toStringMethod = typeof(int).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, new Type[] {typeof(CultureInfo) }, null); var func42 = (Func<CultureInfo,string>)Delegate.CreateDelegate(typeof(Func<CultureInfo,string>), 42, toStringMethod,true); Console.WriteLine( object.ReferenceEquals(func37.Method,func42.Method)); //true Console.WriteLine(func37.Target);//37 Console.WriteLine(func42.Target);//42 Console.WriteLine(func37(CultureInfo.InvariantCulture));//37 Console.WriteLine(func42(CultureInfo.InvariantCulture));//-201040128... WTF?
4 Réponses :
Je ne suis pas sûr, mais peut être Ouvrir les délégués A> peut vous aider. p>
upd upd: suivez ce lien , Si le premier ne fonctionne pas. p>
Ce lien mène à une 404 page - vous êtes peut-être mis en erreur?
Weird, en cliquant sur le lien qui m'amène à une page 404, rafraîchissant la page provoque le même 404 - mais appuyez sur Entrée dans la barre d'URL (c'est-à-dire supprimer le référateur) apporte la page. Certains bugs de navigateur / serveur, apparemment (FF3.5.1 uniquement - chrome fonctionne bien). De toute façon, j'ai trouvé la page maintenant ;-)
Merci, Eamon. C'est la première fois que je vois ce bogue, généralement des liens de blogueurs fonctionnent bien.
La voie du goog peut peut-être utiliser le type "dynamique" dans .NET 4.0. Cependant, le délégué a besoin de l'instance (pour des méthodes non statiques). Les problèmes sont plus complexes puis des loks à la première fois à cause de polymorfisme, etc. p>
Vous avez effectivement choisi un exemple particulièrement délicat, pour deux raisons:
objet code> mais remplacé dans int32 code>. li>.
-
int code> est un type de valeur et il y a des règles étranges avec délégué.createdélégate () code> En ce qui concerne les types de valeur et les méthodes d'instance - le premier paramètre effectif devient essentiellement ref int code> plutôt que int code> li>
ul> Cependant, voici un exemple de string.toupper code>, qui n'a pas non plus de ces problèmes: p> xxx pré> si C'est assez bon pour vous, super ... si vous voulez vraiment int.tostring code>, je vais devoir essayer un peu plus difficile :) p> Voici un exemple de type de valeur , en utilisant un nouveau type de délégué qui prend son premier paramètre par référence: p> xxx pré> p>
C'est l'un de ces cas où il devient clair que c # a encore de la place pour devenir une langue fonctionnelle. Traiter les fonctions de citoyens de première classe n'est toujours pas aussi transparente que nous le souhaitons. Y a-t-il un moyen d'exploiter les fonctionnalités dynamiques du C # 4 pour rendre ce genre de chose plus facile?
@Lbushkin: Je ne pense pas. En fait, la typage dynamique et les lambdas ne vont pas terriblement bien ensemble pour commencer avec - le compilateur doit savoir quel type pour convertir l'expression de Lambda à la compilation.
Je avait i> Tests sur Int.Tostring, mais pour une utilisation réelle, je suppose que je pouvais faire sans méthodes virtuelles - bien que non sans structs. De toute façon, merci pour la tête, j'avais négligé la complexité des méthodes virtuelles et le message d'erreur n'est pas exactement informatif ...
Wow, tu es rapide ;-). Je ne suis pas sûr que ce soit possible - j'ai essayé de regarder à travers MethodInfo.invoke avec le réflecteur pour voir si elle traite des structs spécialement, mais cela finit par un code natif (certains talons CLR, sans aucun doute).
On dirait que INT est un cas particulier? Le code semblable à votre ne fonctionne pas pour un int. Bizarre. Ce n'est pas qu'il soit impossible de faire des solutions de contournement pour des types de construction, mais c'est étrange.
@Amon: Quelle méthode essayiez-vous d'utiliser? Il faudrait être une méthode d'instance non virtuelle, je soupçonne. Tout est un peu complexe ...
Y a-t-il une page où votre deuxième point de balle ("règles étranges") est documentée? Je ne trouve aucun endroit où le fait que le premier paramètre devienne transmis par référence sauf cette réponse.
@Lazlo: Je ne suis pas sûr - je ne me souviens pas de détails moi-même, j'ai peur.
10 ans plus tard ... je suppose que la langue manque toujours dans cette zone? J'ai besoin de lier la déléguée à la propriété Getter pour le type de structure inconnu à l'heure de la compilation. :( est-ce même possible?
@Jameshoux: C'est possible i> que certaines des modifications code> ref cod> C # 7 aideraient, mais je ne suis pas sûr. Il serait peut-être préférable de poser une nouvelle question avec votre exemple spécifique et de ce que vous avez essayé.
@ Jonskeet en fait ... On dirait que j'étais complètement confus. Je pensais que votre suggestion de "Reffunc <>" était strictement hypothétique. Vous étiez, en fait en disant que Reffunc est réel! J'ai essayé Reffunc <> et compiler me dit son type inconnu! Ctrl +. ne montre aucune solution. Comment puis-je utiliser Reffunc <>?
@Jameshoux: C'est un type de délégué déclaré dans la catégorie test code>.
@Jonskeet oh mon. J'ai complètement manqué ça. Je pense que je développe une cécité de code ou quelque chose. Lol merci pour la réponse!
Vous pouvez utiliser des lambdas pour obtenir un wrapper statique "un peu" compilé pour votre méthode d'instance.
L'échantillon ci-dessous n'est pas vraiment rapide, mais il devrait être nettement plus rapide que toute invocation dynamique simple. P>
la sortie p> le code p>