web-dev-qa-db-ja.com

インターフェースでコンストラクターを指定できないのはなぜですか?

可能性のある複製:
コンストラクタ署名を定義するインターフェース?

.Netのインターフェイスでコンストラクターを指定できないことは知っていますが、なぜできないのですか?

私の現在のプロジェクトでは、コンストラクタで「エンジン」を渡す必要があることを指定できると本当に便利ですが、できればクラスのXMLコメントで十分です。

51
Pondidum

インターフェースは動作を記述するためです。コンストラクターは動作しません。オブジェクトの構築方法は実装の詳細です。

88
cletus

コンストラクタをどのように呼び出しますか?インターフェイスを使用する場合、通常はインターフェイスのインスタンスを渡します(むしろ参照)。また、1つのクラスがインターフェイスを実装する場合、派生クラスはそのインターフェイスを継承しますが、同じコンストラクターセットを持たない可能性があることにも留意してください。

これで、ジェネリックメソッドで使用するコンストラクターやその他の本質的に静的なメンバーを指定するために、私がstatic interfacesと呼ぶものの使用を見ることができます。 アイデアに関する私のブログ投稿 を参照してください。

28
Jon Skeet

いいえ、投稿された理由により、インターフェース上にコンストラクターを持つことはできません。ただし、抽象クラスでは可能です。たとえば、この基本クラスがあるとします。

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

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

引数を取らないコンストラクター(デフォルトコンストラクター)がないことに注意してください。つまり、ClassOneから継承するクラスは、2つの引数を持つコンストラクターを呼び出す必要があります。

したがって、これは無効であり、コンパイルされません。

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

ただし、これは有効であり、コンパイルされます。

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

ここで、C#では1つの基本クラスからしか継承できないことを指摘したいと思います。これは特定の状況に対する正しい解決策ではないかもしれませんが、考えるべきことです。

トニー。

9
Tony

すでに投稿されている他のすべての理由の中で、クラスがいくつかのインターフェイスを簡単に実装できることにも留意してください。どのコンストラクタを使用する必要がありますか?

8
M.Turrini

他の回答では、インターフェイスにコンストラクタ宣言をするのが理にかなっていない理由をすでに指摘しています。しかし、あなたの質問から、おそらく abstract factory pattern を探しているのではないかと推測しています。

質問に基づいて例を挙げると、「エンジン」をコンストラクターに渡す必要があることを何らかの形で宣言したいということです。これを行うには、次のような構築サービス用の個別のインターフェイスを宣言します。

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

IGadgetインスタンスを作成する必要があるコードは、コンストラクターを直接呼び出す代わりにIGadgetFactoryインスタンスを使用できます。

6
Wim Coenen

ここで示されている他の説明に加えて、とにかくそれらを呼び出すための新しい構文を発明する必要があります。

Dim x as new IDoStuff()

実装が呼び出されますか?

インターフェースをインスタンス化できないため、コンストラクターは意味をなしません。

0
Mork0075