2015-09-23 18 views
7

私は、特定の型を提供するサブクラスを持つgenericsクラスを持っています。ジェネリッククラスを特定の型付きクラスでサブクラス化できますか?

public abstract class GenericBase<T> 
    where T:Interface1 
{ 
} 

I特定の実装でジェネリックサブクラス:

public class Customer: 
    GenericBase<Type1> 

Type1実装Interface1)。

私はこれへの参照を持つ別の抽象基本クラスを持っている:私は、基本クラスのインスタンスにgenericInstanceを割り当てるしようとすると

protected GenericBase<Interface1> genericInstance; 

は最後に、それはそれを言って、私のコンパイラエラーを与えます暗黙的に顧客をGenericBase <Interface1>に変換することはできません。

base.genericInstance = new Customer(); //Compiler error 

CustomerGenericBase<Type1>のサブタイプである、とType1Interface1を実装する場合、私はこのエラーを取得する理由私は理解していません。 GenericBase<Type1>のサブクラスの場合Customerは実質的にGenericBase<Interface1>のタイプではありませんか?

ここでジェネリックについて何か誤解していると思います。この動作を許可する方法はありますか?

+0

C#についてはわかりませんが、これはJavaではうまくいきません。 Javaでは、 'genericInstance'は' protected GenericBase <? 'として宣言されなければなりません。 extends Interface1> genericInstance'(注:実際に動作しているかどうかは試していません)。 – Powerlord

+1

[共分散とContravariance](https://msdn.microsoft.com/en-us/library/ee207183) –

+0

大雑把に言って、ジェネリックスは共変ではない。 'List 'を 'List 'に代入することはできません。そうでないと 'List 'に 'Dog'を追加することができます。本当に' List ' – Powerlord

答えて

9

C#では、共分散(基本型に派生型を割り当てる)を汎用クラスに適用できません。その結果、新しいIGenericBaseインターフェイスのout parameter modifierを使用して、共変量として具体的にマークされたインターフェイスを適用する必要があります。

protected IGenericBase<Interface1> genericInstance = new Customer(); 

public interface IGenericBase<out T> {} 

public abstract class GenericBase<T> : IGenericBase<T> 
    where T:Interface1 {} 

public interface Interface1 {} 

public class Type1 : Interface1 {} 

public class Customer: GenericBase<Type1> {} 
+2

私はC#がJavaの奇妙な ''と ' 'の構文に似た演算子を持っていることを知っていましたが、それらが' 'と' ' – Powerlord

+0

私の型が私のインタフェースの戻り値と入力パラメータの両方として使われていたので、私は共変インタフェースを使うことができませんでした。しかし、少なくとも私は共分散について少しは理解しています。私が以前に扱っていなかったもの。 – GendoIkari

4

C#には一般的なクラスの共分散はありません。基本的に、派生型の引数が少ない変数に派生した型の引数を割り当てることはできません。ただし、パラメータ型が共変位置のみで使用されている場合、つまりメソッドとプロパティの戻り値の型として使用されている場合、インターフェイスで動作することができます。

詳細については、thisおよびその他のドキュメントを参照してください。

関連する問題