ジェネリック型パラメーターの場合、 in
キーワードは、型パラメーターが反変であることを指定します。 ジェネリック インターフェイスとデリゲートでは、 in
キーワードを使用できます。
反変性を使用すると、ジェネリック パラメーターで指定された型よりも派生型を使用できます。 これにより、反変インターフェイスを実装するクラスの暗黙的な変換とデリゲート型の暗黙的な変換が可能になります。 ジェネリック型パラメーターの共変性と反変性は参照型でサポートされていますが、値型ではサポートされていません。
型は、メソッドの戻り値の型ではなく、メソッドのパラメーターの型を定義する場合にのみ、ジェネリック インターフェイスまたはデリゲートで反変として宣言できます。
In
、 ref
、および out
パラメーターは不変である必要があります。つまり、共変でも反変でもありません。
反変型パラメーターを持つインターフェイスを使用すると、そのメソッドは、インターフェイス型パラメーターで指定された型よりも派生型の少ない引数を受け取ることができます。 たとえば、IComparer<T> インターフェイスでは、型 T は反変であり、Employee
がPerson
を継承する場合、特別な変換メソッドを使用せずに、IComparer<Employee>
型のオブジェクトにIComparer<Person>
型のオブジェクトを割り当てることができます。
反変デリゲートには、同じ型の別のデリゲートを割り当てることができますが、ジェネリック型パラメーターの派生が少なくなります。
詳細については、「 共変性と反変性」を参照してください。
反変ジェネリック インターフェイス
次の例は、反変ジェネリック インターフェイスを宣言、拡張、実装する方法を示しています。 また、このインターフェイスを実装するクラスに暗黙的な変換を使用する方法も示します。
// Contravariant interface.
interface IContravariant<in A> { }
// Extending contravariant interface.
interface IExtContravariant<in A> : IContravariant<A> { }
// Implementing contravariant interface.
class Sample<A> : IContravariant<A> { }
class Program
{
static void Test()
{
IContravariant<Object> iobj = new Sample<Object>();
IContravariant<String> istr = new Sample<String>();
// You can assign iobj to istr because
// the IContravariant interface is contravariant.
istr = iobj;
}
}
反変ジェネリック デリゲート
次の例は、反変ジェネリック デリゲートを宣言、インスタンス化、および呼び出す方法を示しています。 また、デリゲート型を暗黙的に変換する方法も示します。
// Contravariant delegate.
public delegate void DContravariant<in A>(A argument);
// Methods that match the delegate signature.
public static void SampleControl(Control control)
{ }
public static void SampleButton(Button button)
{ }
public void Test()
{
// Instantiating the delegates with the methods.
DContravariant<Control> dControl = SampleControl;
DContravariant<Button> dButton = SampleButton;
// You can assign dControl to dButton
// because the DContravariant delegate is contravariant.
dButton = dControl;
// Invoke the delegate.
dButton(new Button());
}
C# 言語仕様
詳細については、C# 言語仕様のを参照してください。 言語仕様は、C# の構文と使用法の決定的なソースです。
こちらも参照ください
.NET