21

J'ai deux méthodes surchargées, une avec un paramètre facultatif.Méthodes surchargées en conflit avec des paramètres optionnels

void foo(string a) { } 
void foo(string a, int b = 0) { } 

maintenant j'appelle:

foo("abc"); 

fait intéressant la première surcharge est appelée. pourquoi pas la deuxième surcharge avec la valeur optionnelle réglée à zéro?

Pour être honnête, je m'attendrais à ce que le compilateur apporte une erreur, au moins un avertissement pour éviter l'exécution involontaire de la mauvaise méthode.

Quelle est la cause de ce comportement? Pourquoi l'équipe C# l'a-t-elle définie ainsi?

+2

C'est exactement le genre de mauvaise conception de langage qui conduit à des bugs insidieux. Il pourrait également être facilement exploité par un initié à des fins d'espionnage d'entreprise. Je souhaite qu'ils bloqueraient la langue de permettre déjà cela. –

Répondre

27

De MSDN:

If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

14

Une surcharge qui ne nécessite aucun paramètre facultatif à remplir automatiquement est préférable à une surcharge. Cependant, il n'y a pas de préférence entre remplir un argument automatiquement et remplir plus d'un - ainsi, par exemple, cela provoquera une erreur de compilation:

void Foo(int x, int y = 0, int z = 0) {} 
void Foo(int x, int y = 0) {} 
... 
Foo(5); 

Notez que Foo (5, 5) serait résolu à la deuxième méthode, car il ne nécessite pas de paramètres facultatifs seront automatiquement remplis

de la section 7.5.3.2 du C# 4 spécifications:.

Otherwise if all parameters of MP have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in MQ then MP is better than MQ.

Je pense que dans la plupart des cas est le comportement auquel la plupart des gens s'attendraient, pour être honnête. Cela devient bizarre quand vous introduisez des méthodes de classe de base dans le mélange, mais cela a toujours été le cas.

+2

Merci pour votre réponse.Encore une question demeure: POURQUOI l'ont-ils défini ainsi? Y a-t-il un scenerio où la surcharge avec le paramètre optionnel a du sens? Il ne sera jamais appelé avec la valeur par défaut, non? Mais cela peut conduire à des erreurs non désirées. Je pense toujours que le complicateur devrait donner au moins un avertissement. Et il y a d'autres exemples où le développeur doit dire explicitement au compilateur qu'il est conscient de ce qu'il fait. Par exemple, si un paramètre dans une méthode est déclaré comme ref, j'ai besoin d'utiliser explicitement le mot-clé ref dans l'appel de la méthode; sinon, il ne compilera pas. – Thomas

+2

@Thomas: Je crains de ne pas avoir de réponse pour la raison d'être - bien qu'Eric Lippert puisse le faire. Cependant, je ne voudrais pas que vous ajoutiez d'autres bagages * au code d'appel - après tout, la raison pour laquelle les paramètres par défaut sont précisément de * réduire * la quantité de code dont vous avez besoin. –

7

Imaginez si elle était le contraire. Vous avez eu une application. Il a eu une méthode:

void foo(string a) { } 

Tout a fonctionné bien. Maintenant, vous voulez ajouter une surcharge supplémentaire avec un paramètre facultatif:

void foo(string a, int b = 0) { } 

Boom! Tous les appels de méthode vont à la nouvelle méthode. Chaque fois que vous le voulez ou non. L'ajout d'une surcharge de méthode peut entraîner des appels de méthode erronés dans toute l'application. De mon point de vue, dans ce cas, vous auriez beaucoup plus d'occasions de casser votre code (ou celui d'une autre personne).

En outre, OptionalAttribute a été ignoré en C# jusqu'à la version 4.0, mais vous pouvez l'utiliser. Et certaines personnes l'utilisaient dans le code C# pour prendre en charge certains scénarios d'interopérabilité avec d'autres langages, tels que Visual Basic, ou pour COM interop. Maintenant C# l'utilise pour les paramètres optionnels. Ajouter des avertissements/erreurs peut introduire un changement de rupture pour ces applications.

Il peut y avoir d'autres raisons, mais c'est ce qui me vient à l'esprit en premier.

+4

Il devrait afficher une erreur de compilation ou un avertissement d'analyse de code à la place. – Monstieur

+0

@Locutus Vous semblez n'avoir pas lu l'avant-dernier paragraphe de la réponse d'Alexandra. – JLRishe

Questions connexes