Liaison d'arguments pour l'appel de méthode firstProcess.Calculate(x: 1, y: 2)
est fait au moment de la compilation mais la distribution des méthodes est faite au moment de l'exécution parce que la méthode est virtual
.
Afin de compiler l'appel de méthode, le compilateur voit x: 1, y: 2
et doit résoudre cette liste d'arguments nommés en une liste d'arguments indexés séquentiellement afin d'émettre le IL approprié (pousser les arguments sur la pile dans le bon ordre, puis appeler la méthode).
En plus de la liste d'arguments nommés, il y a une autre information disponible pour le compilateur : le paramètre statique type de firstProcess
qui est FirstProcess
. Maintenant, nous savons tous les deux qu'au moment de l'exécution, ce sera un SecondProcess
mais le compilateur ne le sait pas (du moins dans le cas général). Il consulte donc la liste des paramètres de FirstProcess.Calculate
et voit que x
est le premier argument, y
est le second. Cela permet de compiler votre code comme si vous aviez écrit
firstProcess.Calculate(1, 2);
Sur temps de fonctionnement les arguments 1
y 2
sont poussés sur la pile et un appel virtuel est fait à Calculate
. Bien sûr, cela finit par appeler SecondProcess.Calculate
mais les noms des paramètres n'ont pas survécu à la transition vers l'exécution. SecondProcess.Calculate
accepte 1
comme premier argument ( y
) et 2
comme deuxième argument ( x
), ce qui conduit au résultat observé.
En passant, c'est également ce qui se passe lorsque vous utilisez des valeurs d'arguments par défaut :
public class FirstProcess
{
public virtual void Calculate(int x = 10)
{
Console.WriteLine("First Process X :{0}", x);
}
}
public class SecondProcess : FirstProcess
{
public override void Calculate(int x = 20)
{
Console.WriteLine("Second Process X :{0}", x);
}
}
var secondProcess = new SecondProcess();
var firstProcess = (FirstProcess) secondProcess;
secondProcess.Calculate(); // "Second Process X: 20"
firstProcess.Calculate(); // "Second Process X: 10"
La morale de l'histoire : les arguments nommés et par défaut sont pratiques, mais la manière dont ils sont (nécessairement) mis en œuvre vous expose à de mauvaises surprises. Utilisez-les lorsqu'ils offrent de réels avantages tangibles, pas chaque fois que vous le pouvez.