2017-03-19 9 views
1

ユースケース:ジェネリック型のインスタンスを作成するのがなぜこのように機能しますか?

class A {}; 

class B : A {}; 

class C : A {}; 

class Foo <T>: where T : A { 
... 

// T bar = new T(arg1, arg2); 

... 

} 

class FooB: Foo<B> {...} 

class FooC: Foo<C> {...} 

私はFooの子供を対応してクラスAの子供を使いたいです。 FooAFooBには、それぞれABでのみ動作する余分なロジックがあります。参考として、これは正しいシナリオであると感じているので、これを行うには適切な方法だと思うが、他の場所の情報は見ていない。


は、コンパイラはTが適切であるか、コンストラクタAの子でなければならないという制約に基づいて、それを見ることはできないでしょうか?私は現在、new()という制約を追加して、新しく作成されたオブジェクトに対してメソッドを呼び出すことができます。これはまたhere in a similar questionで行われました。私が理解できないことは、コンパイラが未知の型のメソッドを呼び出すことができますが、それをインスタンス化できないことです。特にそうするような制約がある。

例えば

、なぜ私はのような何かを行うことができます。

public class A 
{ 
    public int SomeInt { get; set; } 

    public A(int someInt) 
    { 
     this.SomeInt = someInt; 
    } 
} 

public class B : A 
{ 
} 

Aとのパブリックデフォルトコンストラクタがない、ので、これはコンパイルされません。

class Foo <T>: where T: A, new() { 
... 
T bar = new T() 
bar.Construct(arg1, arg2); 
... 
+0

残念ながら、コンパイラはどのコンストラクタが呼び出される必要があるか分かりません。 –

+0

メソッドがインターフェイスに実装されていることを伝える必要があります。コンパイラが未知の型のメソッドを呼び出すことができる理由は間違っています。タイプが不明ではないためです。インタフェース、クラスには制約があります。コンパイラがジェネリック型のメソッドを呼び出すことができます。 –

答えて

2

をさんは、次のクラスを調べてみましょうコンパイラはABから初期化する方法を知らない。

他のメンバーとは異なり、インスタンスコンストラクタは継承されません、そしてクラスが実際にクラスで宣言されたもの以外のインスタンスコンストラクタを持っていない:
マイクロソフトdocumentationから: コンストラクタは、C#で継承されません。クラスにインスタンスコンストラクタが指定されていない場合、パラメータのない空のコンストラクタが自動的に提供されます。

確かに、我々はそれを修正します後、私たちはBクラスからSomeIntプロパティを呼び出すことができます。結局のところ、相続が何であるか。

コンパイラは実行時にT型のために定義されるコンストラクタを知りません。しかし、そのメソッド/プロパティにアクセスできるAのサブクラス以来、それは知っています。

関連する問題