Une chose à noter ici est que la version de remplacement est appelée à chaque fois. Changer le remplacer:
public override void MyMethod(string s = "bbb")
{
Console.Write("derived: ");
base.MyMethod(s);
}
Et la sortie est:
derived: bbb
derived: aaa
Une méthode dans une classe peut faire un ou deux des éléments suivants:
- Il définit une interface pour un autre code d'appel.
- Il définit une mise en œuvre pour exécuter lors de l'appel.
Il ne peut pas faire les deux, comme une méthode abstraite ne s'occupe que de l'ancien.
Au sein d' BBB
l'appel MyMethod()
appelle une méthode définie en AAA
.
Parce qu'il ya un remplacement en BBB
, en appelant cette méthode aboutit à une mise en œuvre en BBB
de la demande.
Maintenant, la définition de l' AAA
informe le code appelant, de deux choses l'une (enfin, quelques autres encore qui n'ont pas d'importance ici).
- La signature
void MyMethod(string)
.
- (Pour les langues qui le prennent en charge) la valeur par défaut pour le paramètre
"aaa"
et, par conséquent, lors de la compilation d'un code de la forme MyMethod()
si aucune méthode d'appariement MyMethod()
peut être trouvé, vous pouvez le remplacer par un appel à " MyMethod("aaa").
Donc, c'est ce que l'appel en BBB
fait: Le compilateur voit un appel à l' MyMethod()
, ne trouve pas une méthode MyMethod()
mais n'trouver une méthode MyMethod(string)
. Il voit aussi qu'à l'endroit où il a été défini il y a une valeur par défaut de "aaa", donc au moment de la compilation, ça change de ce à un appel à l' MyMethod("aaa")
.
À partir de l'intérieur d' BBB
, AAA
est considéré comme le lieu où l' AAA
's méthodes sont définies, même si substituée en BBB
, de sorte qu'ils peuvent être ignoré.
Au moment de l'exécution, MyMethod(string)
est appelée avec l'argument "aaa". Parce qu'il n'y est substituée à la forme, qui est la forme dite, mais il n'est pas appelé à "bbb", parce que la valeur n'a rien à voir avec le moment de l'exécution de la mise en œuvre, mais avec le moment de la compilation définition.
L'ajout d' this.
des changements de définition qui est examiné, et donc les changements que argument est utilisé dans l'appel.
Edit: Pourquoi ce qui semble le plus intuitif pour moi.
Personnellement, et depuis que je suis à parler de ce qui est intuitif, il ne peut être personnel, je trouve cela plus intuitive pour la raison suivante:
Si j'étais codage BBB
alors que l'appel ou de la transgression MyMethod(string)
, je pense, en tant que "faisant AAA
trucs" - BBB
s prendre sur de "faire l' AAA
trucs", mais elle fait AAA
trucs tout de même. Par conséquent, si l'appel ou de la transgression, je vais être conscient du fait qu'il a été AAA
que définis MyMethod(string)
.
Si j'étais le code appelant, qui a utilisé BBB
, je pense à "utiliser BBB
trucs". Je ne pourrais pas être très au courant de ce qui a été défini dans AAA
,, et je n'aurais peut-être penser à cela comme un simple détail de l'implémentation (si je n'ai pas également utiliser l' AAA
interface de proximité).
Le compilateur du comportement correspond à mon intuition, c'est pourquoi lors de la première lecture de la question, il me semblait que les Mono avait un bug. Après réflexion, je ne vois pas comment, soit remplit les comportements spécifiques, mieux que les autres.
Pour que la matière même si, tout en restant à un niveau personnel, je n'avais jamais utiliser les paramètres facultatifs dans l'abstrait, virtuel ou de méthodes de remplacement, et si une substitution de quelqu'un d'autre qui l'a fait, j'aimerais correspondre à la leur.