2011-11-14 3 views
4

Considérons l'application console suivante:C# 4.0 Paramètres par défaut

class Program 
{ 
    static void Main() 
    { 
     MyInterface test = new MyClass(); 
     test.MyMethod(); 

     Console.ReadKey(); 
    } 
} 

interface MyInterface 
{ 
    void MyMethod(string myString = "I am the default value on the interface"); 
} 

class MyClass : MyInterface 
{ 
    public void MyMethod(string myString = "I am the default value set on the implementing class") 
    { 
     Console.WriteLine(myString); 
    } 
} 

La sortie de ce programme est:

I am the default value on the interface 

(1) Pourquoi est-il pas un moyen de spécifier un paramètre comme facultatif sur une interface sans fournir de valeur. Je considère que la valeur par défaut est le détail de l'implémentation. Si nous écrivions ce code dans le style de paramètre pré-optionnel, nous créerions deux surcharges dans l'interface et la valeur par défaut serait spécifiée dans la classe d'implémentation. C'est à dire. nous aurions:

interface MyInterface 
{ 
    void MyMethod(); 

    void MyMethod(string myString); 
} 

class MyClass : MyInterface 
{ 
    public void MyMethod() 
    { 
     MyMethod("I am the default value set on the implementing class"); 
    } 

    public void MyMethod(string myString) 
    { 
     Console.WriteLine(myString); 
    } 
} 

qui sort comme on pouvait s'y attendre,

I am the default value set on the implementing class 

(2) Pourquoi ne pouvons-nous remplacer la valeur par défaut dans la classe implémentant!

Répondre

4

Les valeurs par défaut dans .Net sont en réalité du sucre syntaxique basé sur un compilateur. Sur le site d'appel, le compilateur ajoute les valeurs par défaut pour vous. Il ne peut pas connaître le type d'exécution de votre objet lors de la compilation, il doit donc insérer la valeur définie dans l'interface. Par conséquent, ils ne peuvent pas être remplacés dans les implémentations car il n'y a rien à redéfinir.

Eric Lippert a écrit une série très intéressante de billets de blog sur le thème des arguments optionnels, dont le premier peut être trouvé here.

Mise à jour
De vos commentaires, ce que vous proposez est soit une certaine forme de paramètre « virtuel » (dans lequel le type d'exécution déclare), que le CLR devrait « savoir » au sujet. Je suppose que cette implémentation a été exclue parce que les coûts (conception, documentation, implémentation, test, etc.) étaient trop élevés par rapport aux avantages qu'elle procurait (bien que ce ne soit qu'une supposition!). Sinon, il y a l'option de méthode déléguer par défaut à savoir:

void M(bool y = false) { ... whatever ... } 

est ré-écrit par le compilateur comme:

void M() { M(false); } 
void M(bool y) { ... whatever ... } 

Mais en descendant cette route mène à un niveau potentiellement inacceptable de surcharges une fois plusieurs arguments optionnels et les arguments nommés sont pris en considération.

+0

A bientôt Rich, je vois le problème. Ne serait-il pas plus logique pour eux d'avoir ajouté un mot clé "optionnel" plutôt que d'avoir à fournir une valeur à l'interface? Cela n'a aucun sens pour moi d'avoir à mettre une valeur par défaut sur l'interface. – magritte

3

1) Il y a un défaut dans votre façon de penser. Vous dites que la valeur par défaut est un détail d'implémentation. Les interfaces sont exemptes de détails d'implémentation. Selon cette logique, spécifier une valeur par défaut n'appartient vraiment pas à une interface. Il suffit d'écrire l'interface en utilisant des méthodes surchargées. Non seulement la définition sera plus claire, mais l'interface sera plus compatible lors de l'interfaçage avec d'autres langages et vous n'aurez pas les problèmes de version avec les paramètres optionnels.

2) Parce que l'interface définit un contrat opérationnel. L'interface dit que la valeur par défaut doit être quelque chose ... donc la classe doit l'implémenter de cette façon.

+0

(1) En effet, je suis d'accord, cependant si vous l'omettez, vous obtiendrez un avertissement du compilateur car il ne saura pas que le paramètre est optionnel. Cela conduit à ma question (1) Pourquoi ne pouvez-vous pas le spécifier comme optionnel sans fournir une valeur? – magritte

+0

@Tony Leeper - Également obtenu cette bonne série de cas d'angle d'Eric Lippert via Twitter: http://blogs.msdn.com/b/ericlippert/archive/2011/05/09/optional-argument-corner-cases-part -one.aspx –

Questions connexes