413 votes

Pourquoi C# 4 paramètres facultatifs sont définies sur l’interface ne pas appliquée sur l’implémentation de classe ?

J'ai remarqué qu'avec l'option paramètres en C# 4 si vous spécifiez un paramètre facultatif sur une interface vous N'avez PAS à prendre ce paramètre en option sur toute la mise en œuvre de la classe:

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

Personne ne sait pourquoi les paramètres facultatifs sont conçus pour fonctionner de cette façon?

D'une part, je suppose que la capacité de remplacer les valeurs par défaut spécifiées sur les interfaces est utile, mais pour être honnête, je ne suis pas sûr si vous devez même être en mesure de spécifier les valeurs par défaut de l'interface comme cela devrait être une décision de mise en œuvre.

D'autre part, ce décalage signifie que vous ne pouvez pas toujours utiliser le béton de la classe et de l'interface de façon interchangeable. Ce qui bien sûr, ne serait pas un problème si la valeur par défaut est spécifiée sur la mise en œuvre, mais si vous êtes exposant votre classe concrète de l'interface (à l'aide de certains CIO cadre d'injecter du béton de classe par exemple), alors il n'y a aucun point d'avoir la valeur par défaut que l'appelant devra toujours fournir de toute façon.

274voto

Eric Lippert Points 300275

Mise à JOUR: Cette question a été l'objet de mon blog le 12 Mai 2011. Merci pour la grande question!

Supposons que vous disposez d'une interface comme vous le décrivez, et une centaine de classes qui l'implémentent. Puis vous décidez de faire l'un des paramètres de l'un de l'interface des méthodes facultatif. Suggérez-vous que la bonne chose à faire est de le compilateur à force de le développeur à trouver chaque mise en œuvre de la méthode de l'interface, et de rendre le paramètre facultatif?

Supposons que nous l'avons fait. Supposons maintenant que le développeur n'a pas le code source de l'application:


// in metadata:
public class B 
{ 
    public void TestMethod(bool b) {}
}

// in source code
interface MyInterface 
{ 
    void TestMethod(bool b = false); 
}
class D : B, MyInterface {}
// Legal because D's base class has a public method 
// that implements the interface method

Comment est l'auteur de D censé faire ce travail? Sont-ils nécessaires dans votre monde pour appeler l'auteur de B sur le téléphone et demandez-leur de prière de les expédier une nouvelle version de B qui rend la méthode ont un paramètre facultatif?

Cela ne va pas voler. Que faire si deux personnes, d'appeler l'auteur de B, et l'un d'eux veut le défaut d'être vrai et l'un d'eux veut-il être faux? Si l'auteur de B tout simplement refuse de jouer le jeu?

Peut-être, dans ce cas, ils seraient tenus de dire:

class D : B, MyInterface 
{
    public new void TestMethod(bool b = false)
    {
        base.TestMethod(b);
    }
}

Le projet semble à ajouter beaucoup de désagréments pour le programmeur n'ayant pas connu d'augmentation du pouvoir représentatif. Quel est l'irrésistible avantage de cette fonctionnalité qui justifie l'augmentation du coût pour l'utilisateur?

50voto

CodesInChaos Points 60274

Un paramètre facultatif est juste marqué avec un attribut. Cet attribut indique au compilateur d'insérer la valeur par défaut pour ce paramètre lors de l'appel-site.

L'appel obj2.TestMethod(); est remplacé par obj2.TestMethod(false); lorsque le C# code sera compilé à l'IL, et pas à JIT-temps.

Donc dans un sens, c'est toujours l'appelant de fournir la valeur par défaut avec les paramètres facultatifs. Cela a aussi des conséquences sur la gestion des versions binaires: Si vous modifiez la valeur par défaut, mais ne pas recompiler le code appelant, il va continuer à utiliser l'ancienne valeur par défaut.

D'autre part, ce décalage signifie que vous ne pouvez pas toujours utiliser le béton de la classe et de l'interface de façon interchangeable.

Déjà vous ne pouvez pas le faire si la méthode de l'interface a été mis en œuvre explicitement.

33voto

Olhovsky Points 2817

Parce que les paramètres par défaut sont résolues au moment de la compilation, pas de DUREE. Si les valeurs par défaut n’appartient pas à l’objet appelé, mais pour le type de référence qu’il est appelé à travers.

7voto

Ariel Arjona Points 125

Les paramètres facultatifs sont un peu comme une substitution de macro de ce que je comprends. Ils ne sont pas vraiment en option du point de vue de la méthode. Un artefact de qui est le comportement vous voyez où vous obtenez des résultats différents si vous effectuez un cast en une interface.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X