Pourquoi ne sommes-nous pas autorisés à spécifier un constructeur dans une interface? [dupliquer]

possibilité de dupliquer:

Interface définissant une signature de constructeur?

je sais que vous ne pouvez pas spécifier un constructeur dans une interface dans .Net, mais pourquoi ne le pouvons-nous pas?

il serait vraiment utile pour mon projet actuel de pouvoir spécifier qu'un "moteur" doit être passé avec le constructeur, mais comme je ne peux pas, je dois suffire avec un commentaire XML sur la classe.

51
demandé sur Community 2009-03-27 14:53:47

7 réponses

parce qu'une interface décrit le comportement. Les constructeurs ne sont pas des comportements. Comment un objet est construit est un détail d'implémentation.

88
répondu cletus 2009-03-27 11:57:10

comment appelleriez-vous le constructeur? Lorsque vous utilisez des interfaces, vous passez normalement une instance de l'interface autour (ou plutôt, une référence). Aussi garder à l'esprit que si une classe implémente une interface, une classe dérivée hérite de l'interface, mais ne peut pas avoir le même ensemble de constructeurs.

maintenant, je peux voir l'utilisation de ce que j'appelle interfaces statiques pour spécifier les constructeurs et d'autres éléments essentiellement statiques pour une utilisation en Générique méthode. Voir mon blog sur l'idée pour plus d'informations.

28
répondu Jon Skeet 2014-11-27 05:12:56

Non vous ne pouvez pas avoir de constructeurs sur les interfaces pour les raisons qui ont été affichées. Cependant, vous pouvez sur des classes abstraites. Disons par exemple que vous avez cette classe de base.

public abstract class ClassOne
{
    protected int _x;
    protected string _s;

    public ClassOne(int x, string s)
    {
        _x = x;
        _s = s;
    }        
}

avis il n'y a aucun constructeur qui ne prend aucun argument (constructeur par défaut) ce qui signifie que toute classe qui hérite de ClassOne doit appeler le constructeur qui a 2 arguments.

donc ceci n'est pas valide et ne compilera pas.

public class ClassTwo : ClassOne
{
    public ClassTwo() 
    { }
}

Cependant, cela est valide et la compilation.

public class ClassTwo : ClassOne
{
    public ClassTwo(int x, string s) : base(x, s)
    {  }
}

je tiens à souligner ici que, en C# vous ne pouvez hériter d'une classe de base. Ce qui veut dire que ce n'est peut-être pas la bonne solution pour une situation particulière, mais c'est quelque chose à laquelle il faut réfléchir.

Tony.

9
répondu Tony 2009-03-27 12:12:39

parmi toutes les autres raisons déjà publiées, gardez aussi à l'esprit que la classe a peut facilement implémenter plusieurs interfaces; quel constructeur devrait être utilisé alors?

8
répondu M.Turrini 2009-03-27 13:18:41

D'autres réponses ont déjà souligné pourquoi il n'est pas logique d'avoir une déclaration du constructeur sur une interface. Mais de votre question, je devine que vous cherchez probablement le abstract factory pattern .

Pour donner un exemple basé sur votre question: vous dites que vous voulez en quelque sorte déclarer qu'un "moteur" doit être transmis au constructeur. Vous pouvez le faire en déclarant une interface séparée pour une construction service comme ceci:

public interface IGadgetFactory
{
   IGadget CreateGadget(Engine engine);
}

tout code qui doit créer des instances IGadget peut alors utiliser une instance IGadgetFactory au lieu d'appeler directement n'importe quel constructeur.

6
répondu Wim Coenen 2009-03-27 13:38:23

parce que vous ne pouvez pas instancier une interface, donc un doenst de constructur a du sens.

0
répondu Mork0075 2009-03-27 11:56:07

outre les autres explications données ici, vous devrez inventer une nouvelle syntaxe pour les appeler de toute façon, puisque si vous avez deux ou plusieurs implémentations dans la portée à la ligne:

Dim x as new IDoStuff()

pourquoi l'implémentation est-elle appelée?

0
répondu Damien_The_Unbeliever 2009-03-27 14:21:59