Le code suivant a une méthode statique, Foo()
appelant une méthode d'instance, Bar()
:
public sealed class Example
{
int count;
public static void Foo( dynamic x )
{
Bar(x);
}
void Bar( dynamic x )
{
count++;
}
}
Il se compile sans erreur * mais génère une exception de liant d'exécution lors de l'exécution. La suppression du paramètre dynamique de ces méthodes provoque une erreur du compilateur, comme prévu.
Alors, pourquoi avoir un paramètre dynamique permet-il de compiler le code? ReSharper ne l'affiche pas non plus comme une erreur.
Edit 1: * dans Visual Studio 2008
Edit 2: ajouté sealed
car il est possible qu'une sous-classe puisse contenir une Bar(...)
méthode statique . Même la version scellée se compile lorsqu'il n'est pas possible qu'une méthode autre que la méthode d'instance puisse être appelée au moment de l'exécution.
c#
visual-studio-2008
dynamic
compiler-errors
Mike Scott
la source
la source
dynamic
sauf si vous en avez vraiment besoin.Réponses:
MISE À JOUR: La réponse ci-dessous a été écrite en 2012, avant l'introduction de C # 7.3 (mai 2018) . Dans Quoi de neuf dans C # 7.3 , la section Candidats de surcharge améliorés , élément 1, il est expliqué comment les règles de résolution de surcharge ont changé afin que les surcharges non statiques soient supprimées tôt. Donc, la réponse ci-dessous (et toute cette question) n'a pour la plupart qu'un intérêt historique maintenant!
(Pré C # 7.3 :)
Pour une raison quelconque, la résolution de surcharge trouve toujours la meilleure correspondance avant de vérifier les statiques par rapport aux non statiques. Veuillez essayer ce code avec tous les types statiques:
Cela ne compilera pas car la meilleure surcharge est celle qui prend un
string
. Mais bon, c'est une méthode d'instance, donc le compilateur se plaint (au lieu de prendre la deuxième meilleure surcharge).Ajout: Je pense donc que l'explication de l'
dynamic
exemple de la question originale est que, pour être cohérent, lorsque les types sont dynamiques, nous trouvons également d' abord la meilleure surcharge (ne vérifiant que le nombre de paramètres et les types de paramètres, etc., pas statique vs non -static), et ensuite seulement vérifier l'électricité statique. Mais cela signifie que la vérification statique doit attendre l'exécution. D'où le comportement observé.Ajout tardif: Des informations sur les raisons pour lesquelles ils ont choisi de faire des choses dans cet ordre amusant peuvent être déduites de ce billet de blog d'Eric Lippert .
la source
dynamic
été introduit dans le langage, je pense que les concepteurs de C # ont dit: "Nous ne prendrons pas en considération (2) la compilation quand c'est unedynamic
expression." Mon but ici est donc de trouver une idée de la raison pour laquelle ils ont choisi de ne pas vérifier la statique par rapport à l'instance jusqu'à l'exécution. Je dirais que ce contrôle a lieu au moment de la liaison .Foo a un paramètre "x" qui est dynamique, ce qui signifie que Bar (x) est une expression dynamique.
Il serait parfaitement possible pour Example d'avoir des méthodes comme:
Dans ce cas, la méthode correcte serait résolue, donc l'instruction Bar (x) est parfaitement valide. Le fait qu'il existe une méthode d'instance Bar (x) est sans importance et même pas pris en compte: par définition , puisque Bar (x) est une expression dynamique, nous avons reporté la résolution à l'exécution.
la source
L'expression "dynamique" sera liée pendant l'exécution, donc si vous définissez une méthode statique avec la signature correcte ou une méthode d'instance, le compilateur ne la vérifiera pas.
La «bonne» méthode sera déterminée pendant l'exécution. Le compilateur ne peut pas savoir s'il existe une méthode valide pendant l'exécution.
Le mot-clé "dynamic" est défini pour les langages dynamiques et de script, où la méthode peut être définie à tout moment, même pendant l'exécution. Des trucs fous
Voici un exemple qui gère les entiers mais pas de chaînes, car la méthode est sur l'instance.
Vous pouvez ajouter une méthode pour gérer tous les "faux" appels, qui n'ont pas pu être traités
la source