J'ai remarqué qu'avec les paramètres facultatifs en C # 4 si vous spécifiez un paramètre facultatif sur une interface que vous n'avez pas, ne devez pas rendre ce paramètre facultatif sur n'importe quelle classe d'implémentation:
public interface MyInterface
{
void TestMethod(bool flag = false);
}
public class MyClass : MyInterface
{
public void TestMethod(bool flag)
{
Console.WriteLine(flag);
}
}
et donc:
var obj = new MyClass();
obj.TestMethod(); // compiler error
var obj2 = new MyClass() as MyInterface;
obj2.TestMethod(); // prints false
Est-ce que quelqu'un sait pourquoi les paramètres facultatifs sont conçus pour fonctionner de cette façon?
D'une part, je suppose que la possibilité de remplacer toutes les valeurs par défaut spécifiées sur les interfaces est utile, mais pour être honnête, je ne sais pas si vous devriez même être en mesure de spécifier des valeurs par défaut sur l'interface car cela devrait être une décision d'implémentation.
D'un autre côté, cette déconnexion signifie que vous ne pouvez pas toujours utiliser la classe concrète et l'interface de manière interchangeable. Bien sûr, cela ne serait pas un problème si la valeur par défaut est spécifiée sur l'implémentation, mais si vous exposez votre classe concrète comme interface (en utilisant un cadre IOC pour injecter la classe concrète par exemple), alors vraiment il n'y a pas point ayant la valeur par défaut car l'appelant devra toujours la fournir de toute façon.
MyInterface
et l' appeler avec le paramètre optionnel:((MyInterface)obj).TestMethod();
.Réponses:
MISE À JOUR: Cette question a fait l'objet de mon blog le 12 mai 2011. Merci pour la grande question!
Supposons que vous ayez une interface comme vous le décrivez, et une centaine de classes qui l'implémentent. Ensuite, vous décidez de rendre facultatif l'un des paramètres d'une des méthodes de l'interface. Suggérez-vous que la bonne chose à faire est que le compilateur force le développeur à trouver chaque implémentation de cette méthode d'interface et à rendre le paramètre facultatif également?
Supposons que nous ayons fait ça. Supposons maintenant que le développeur ne disposait pas du code source pour l'implémentation:
Comment l'auteur de D est-il censé faire fonctionner cela? Sont-ils obligés dans votre monde d'appeler l'auteur de B par téléphone et de leur demander de leur envoyer une nouvelle version de B qui rend la méthode un paramètre facultatif?
Ça ne va pas voler. Et si deux personnes appellent l'auteur de B et que l'une d'elles veut que la valeur par défaut soit vraie et que l'une d'elles veuille que ce soit faux? Et si l'auteur de B refuse simplement de jouer le jeu?
Dans ce cas, ils seraient peut-être tenus de dire:
La fonctionnalité proposée semble ajouter beaucoup d'inconvénients pour le programmeur sans augmentation correspondante de la puissance représentative. Quel est l'avantage convaincant de cette fonctionnalité qui justifie l'augmentation des coûts pour l'utilisateur?
MISE À JOUR: Dans les commentaires ci-dessous, supercat suggère une fonctionnalité de langue qui ajouterait véritablement de la puissance à la langue et permettrait certains scénarios similaires à celui décrit dans cette question. Pour info, cette fonctionnalité - implémentations par défaut des méthodes dans les interfaces - sera ajoutée à C # 8.
la source
Un paramètre facultatif est simplement étiqueté avec un attribut. Cet attribut indique au compilateur d'insérer la valeur par défaut de ce paramètre sur le site d'appel.
L'appel
obj2.TestMethod();
est remplacé parobj2.TestMethod(false);
lorsque le code C # est compilé en IL, et non au moment JIT.Donc, d'une certaine manière, c'est toujours l'appelant qui fournit la valeur par défaut avec des paramètres facultatifs. Cela a également des conséquences sur le contrôle de version binaire: si vous modifiez la valeur par défaut mais ne recompilez pas le code appelant, il continuera à utiliser l'ancienne valeur par défaut.
Vous ne pouvez déjà pas le faire si la méthode d'interface a été implémentée explicitement .
la source
Parce que les paramètres par défaut sont résolus au moment de la compilation, pas à l'exécution. Les valeurs par défaut n'appartiennent donc pas à l'objet appelé, mais au type de référence via lequel il est appelé.
la source
Les paramètres facultatifs sont un peu comme une substitution de macro de ce que je comprends. Ils ne sont pas vraiment facultatifs du point de vue de la méthode. Un artefact de cela est le comportement que vous voyez lorsque vous obtenez des résultats différents si vous effectuez un cast sur une interface.
la source