J'ai le code suivant que fort> fait strong> drôle em> trucs: comme vous pouvez le constater, le La sortie du code suivant est très inattendue: p> impression < code> enfant.dossomething (itémable alors que l'assainissement d'un impression Pourquoi ce arrive em> ?! p> p> DOSMATHIAT Code> Méthode dans
Enfant CODE> est remplacé correctement. p>
parent code> référence à
c code> génère la sortie correcte: p>
enfant.dossomething (iEnumerable
3 Réponses :
Cela arrive parce que le compilateur C # obéit la spécification :) p>
La spécification indique que si une méthode déclarée dans un type dérivé est applicable, toute méthode déclarée à l'origine em> dans une classe de base (même si elles sont remplacées dans le type dérivé) sont retirées de l'ensemble. des candidats. P>
Maintenant parce que vous utilisez c # 4 (probablement), il existe une conversion implicite de la liste J'ai un article sur la surcharge qui passe dans cela et d'autres bizarreries. < / p>
Je vous conseille de ne pas surcharger sur des hiérarchies de type - c'est déroutant. P>
ienumerable
enfant.dOsomething (IEnumerable
ienumerable
Je suppose qu'il y a de bonnes raisons de cela, mais je pense que c'est une partie regrettable de la spécification. Il se brise avec le principe du moindre surprise.
Ceci est appelé dans le C # Spécification , partie 7.5.5.1 - Invocations de méthodes, et il existe également un commentaire à ce sujet à la section 7.4.3 - Résolution de la surcharge: Par exemple, l'ensemble des candidats à une méthode d'invocation Non inclure les méthodes marquées de remplacement (§7.3) et les méthodes d'une classe de base ne sont pas des candidats si une méthode d'une classe dérivée est applicable (§7.5.5.1). I>
Mais qu'en est-il du second, pourquoi, en second, il appelle l'article hérité?
@Saeedalg: Parce que la résolution de surcharge i> (compilation) ne sait rien sur les méthodes sur l'enfant. AT EXECUTION I> TIME La méthode remplacée est cueillie comme mise en œuvre de la signature choisie lors de la compilation.
Étant donné que le compilateur utilise uniquement le type de l'objet qu'il connaît, et il ne sait que l'objet prend en charge ce qui est au parent, et il n'en a donc qu'une méthode disponible lors de la résolution de l'invocation de la méthode. Si vous aviez utilisé le nouveau type code> type code> de C # /. NET 4.0, l'appel de la méthode aurait été résolu au moment de l'exécution et revenait à la surcharge de l'objet.
@Lasse: Pour ce que ça vaut la peine, je peux voir le point de retarder les méthodes de rejet qui ne sont pas déclarées du tout par la classe enfant, mais je pense que les méthodes remplacées ne devraient pas être éliminées. L'idée est d'empêcher le problème de la classe de base fragile, où l'ajout d'une méthode à une classe de base rompt les appelants de la classe enfant, lorsque la classe enfant ne connaissait pas le changement. Si vous remplissez la méthode, vous le savez clairement, de sorte que cela ne devrait pas s'appliquer.
Je sais sur les classes de base fragiles et les problèmes qu'ils donnent, je ne suis tout simplement pas sûr que c'est un problème plus important que celui que nous avons actuellement. Bien sûr, tout le point est discutable car cela ne va pas changer maintenant. Bien sûr, puisque je ne connais pas toutes les raisons de cela, il pourrait y avoir d'autres personnes en plus du problème de la classe de base fragile, donc à mon avis i> Je pense que c'est malheureux. Cela pourrait cependant être la meilleure solution. C'est-à-dire que je soupçonne fortement que c'est :)
@lasse, p>
vous avez écrit p>
Parce que le compilateur utilise uniquement le type de l'objet qu'il connaît, et il ne sait que l'objet prend en charge ce qui est dans le parent, et il n'a donc qu'une méthode disponible lors de la résolution de l'invocation de la méthode. P> blockQuote>
Je ne sais pas si je comprends ce que vous dites, mais dans le second cas, car l'instance est une instance d'enfant et la méthode appelée est virtuelle, la résolution de la méthode est effectuée au moment de l'exécution et ne pas compiler temps, et en fait, c'est la méthode de l'enfant qui est appelée. p>
en ce qui concerne les règles de résolution de la méthode. Ne devrait-il pas choisir une méthode plus spécifique? Je sais que c'est un point de théâtre à ce stade. en 3.5 et 2, il choisirait la méthode plus spécifique. P>
Eh bien, j'ai testé votre code dans VS2008 en utilisant un test unitaire. Et je reçois
enfant.dossomething (iEnumerable) code> à la fois dans les deux.
@Draco: il doit être exécuté dans .NET 4.0 / C # 4.0 pour ce comportement à prendre effet, car
list code> est compatible avec
ienumerable code> avec le nouveau Support de variance introduit.
Je n'ai pas été capable de reproduire ce comportement aussi .. VS2010 .NET 4.0 C # et a toujours eu un "enfant.dossomething (iEnumerable)" comme sortie. Vous devez avoir plus de code que cela, causant ce comportement .. S'il vous plaît poster votre code complet et nous verrons pour nous-mêmes.