ジェネリック型パラメーターの場合、 out
キーワードは、型パラメーターが共変であることを指定します。 ジェネリック インターフェイスとデリゲートでは、 out
キーワードを使用できます。
共分散を使用すると、ジェネリック パラメーターで指定された型よりも多くの派生型を使用できます。 これにより、共変インターフェイスを実装するクラスの暗黙的な変換とデリゲート型の暗黙的な変換が可能になります。 参照型では共変性と反変性がサポートされていますが、値型ではサポートされていません。
共変型パラメーターを持つインターフェイスを使用すると、そのメソッドは型パラメーターで指定された型よりも多くの派生型を返します。 たとえば、.NET Framework 4 では、 IEnumerable<T>では T 型が共変であるため、特別な変換メソッドを使用せずに、 IEnumerable(Of String)
型のオブジェクトを IEnumerable(Of Object)
型のオブジェクトに割り当てることができます。
共変デリゲートには、同じ型の別のデリゲートを割り当てることができますが、より派生したジェネリック型パラメーターを使用できます。
詳細については、「 共変性と反変性」を参照してください。
例 - 共変ジェネリック インターフェイス
次の例は、共変ジェネリック インターフェイスを宣言、拡張、実装する方法を示しています。 また、共変インターフェイスを実装するクラスに暗黙的な変換を使用する方法も示します。
// Covariant interface.
interface ICovariant<out R> { }
// Extending covariant interface.
interface IExtCovariant<out R> : ICovariant<R> { }
// Implementing covariant interface.
class Sample<R> : ICovariant<R> { }
class Program
{
static void Test()
{
ICovariant<Object> iobj = new Sample<Object>();
ICovariant<String> istr = new Sample<String>();
// You can assign istr to iobj because
// the ICovariant interface is covariant.
iobj = istr;
}
}
ジェネリック インターフェイスでは、次の条件を満たす場合、型パラメーターを共変として宣言できます。
型パラメーターは、インターフェイス メソッドの戻り値の型としてのみ使用され、メソッド引数の型として使用されません。
注
この規則には 1 つの例外があります。 共変インターフェイスで反変ジェネリック デリゲートをメソッド パラメーターとして使用する場合は、このデリゲートのジェネリック型パラメーターとして共変型を使用できます。 共変ジェネリック デリゲートと反変ジェネリック デリゲートの詳細については、「Func および Action Generic Delegate のデリゲートの分散と分散の使用」を参照してください。
型パラメーターは、インターフェイス メソッドのジェネリック制約として使用されません。
例 - 共変ジェネリック デリゲート
次の例は、共変のジェネリック デリゲートを宣言、インスタンス化、および呼び出す方法を示しています。 また、デリゲート型を暗黙的に変換する方法も示します。
// Covariant delegate.
public delegate R DCovariant<out R>();
// Methods that match the delegate signature.
public static Control SampleControl()
{ return new Control(); }
public static Button SampleButton()
{ return new Button(); }
public void Test()
{
// Instantiate the delegates with the methods.
DCovariant<Control> dControl = SampleControl;
DCovariant<Button> dButton = SampleButton;
// You can assign dButton to dControl
// because the DCovariant delegate is covariant.
dControl = dButton;
// Invoke the delegate.
dControl();
}
ジェネリック デリゲートでは、メソッドの戻り値の型としてのみ使用され、メソッド引数には使用されない型を共変として宣言できます。
C# 言語仕様
詳細については、C# 言語仕様のを参照してください。 言語仕様は、C# の構文と使用法の決定的なソースです。
こちらも参照ください
.NET