4

私は次のコードを持っています。

class Header<T> where T: IItem { }
class HeaderA : Header<ItemA> { } 
class HeaderB : Header<ItemB> { } 

interface IItem { }
class ItemA : IItem { }
class ItemB : IItem { }

Header<IItem> h = new HeaderA();

最後の行はコンパイルできません。

Cannot implicitly convert type 'UserQuery.HeaderA' to 'UserQuery.Header<UserQuery.IItem>'

HeaderAはHeaderのサブタイプであり、ItemAはIItemのサブタイプです。なぜそれが機能しないのですか?

4

1 に答える 1

16

つまり、共分散と呼ばれる概念を使用しようとしています。これは、.NETジェネリッククラスではサポートされておらず、インターフェイスではデフォルトでサポートされていません。

クラスにこれを許可する場合は、ジェネリックインターフェイスでoutcontextualキーワードを使用して、C#3以降で指定できます。

interface IHeader<out T> where T : IItem { }
class Header<T>: IHeader<T> where T:IItem { }
class HeaderA : Header<ItemA> { }
class HeaderB : Header<ItemB> { }

interface IItem { }
class ItemA : IItem { }
class ItemB : IItem { }

public void Foo()
{
    //now this works; notice the use of the interface instead of the base class.
    IHeader<IItem> h = new HeaderA();
}

キーワードを指定してインターフェイスを使用することにより、基本的に、インターフェイスの使用法は、インターフェイスのジェネリック型宣言の制約を満たす(またはオブジェクトである)ことよりも、ジェネリック型について詳しく知る必要がないことをコンパイラに伝えます。そのため、より多くの派生ジェネリックをインターフェイスタイプの変数に割り当てることができるようになりましたが、それらをインターフェイスタイプとしてのみ処理でき、派生タイプとしては処理できません。

outキーワードはクラス定義には使用できません。の使用法を強制的に共変にすることはできませんHeader<T>

于 2012-09-14T20:22:38.227 に答える