C# では、共変性と反変性により、配列型、デリゲート型、およびジェネリック型引数の暗黙的な参照変換が可能になります。 共変性では割り当ての互換性が維持され、反変性によって逆になります。
次のコードは、代入の互換性、共変性、反変性の違いを示しています。
// Assignment compatibility.
string str = "test";
// An object of a more derived type is assigned to an object of a less derived type.
object obj = str;
// Covariance.
IEnumerable<string> strings = new List<string>();
// An object that is instantiated with a more derived type argument
// is assigned to an object instantiated with a less derived type argument.
// Assignment compatibility is preserved.
IEnumerable<object> objects = strings;
// Contravariance.
// Assume that the following method is in the class:
static void SetObject(object o) { }
Action<object> actObject = SetObject;
// An object that is instantiated with a less derived type argument
// is assigned to an object instantiated with a more derived type argument.
// Assignment compatibility is reversed.
Action<string> actString = actObject;
配列の共分散により、より派生型の配列を、より派生の少ない型の配列に暗黙的に変換できます。 ただし、次のコード例に示すように、この操作はタイプ セーフではありません。
object[] array = new String[10];
// The following statement produces a run-time exception.
// array[0] = 10;
メソッド グループの共変性と反変性のサポートにより、メソッド シグネチャをデリゲート型と照合できます。 これにより、一致するシグネチャを持つメソッドだけでなく、より多くの派生型 (共変性) を返すメソッド、またはデリゲート型で指定されたよりも派生型 (反変性) が少ないパラメーターを受け入れるメソッドをデリゲートに割り当てることができます。 詳細については、「 デリゲートの分散 (C#) 」および「 デリゲートでの分散の使用 (C#)」を参照してください。
次のコード例は、メソッド グループの共変性と反変性のサポートを示しています。
static object GetObject() { return null; }
static void SetObject(object obj) { }
static string GetString() { return ""; }
static void SetString(string str) { }
static void Test()
{
// Covariance. A delegate specifies a return type as object,
// but you can assign a method that returns a string.
Func<object> del = GetString;
// Contravariance. A delegate specifies a parameter type as string,
// but you can assign a method that takes an object.
Action<string> del2 = SetObject;
}
.NET Framework 4 以降のバージョンでは、C# はジェネリック インターフェイスとデリゲートの共変性と反変性をサポートし、ジェネリック型パラメーターの暗黙的な変換を可能にします。 詳細については、「 ジェネリック インターフェイスの分散 (C#) 」および「 デリゲートの分散 (C#)」を参照してください。
次のコード例は、ジェネリック インターフェイスの暗黙的な参照変換を示しています。
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;
ジェネリック パラメーターが共変または反変として宣言されている場合、ジェネリック インターフェイスまたはデリゲートは バリアント 型と呼ばれます。 C# を使用すると、独自のバリアント インターフェイスとデリゲートを作成できます。 詳細については、「 バリアント ジェネリック インターフェイスの作成 (C#) 」および「 デリゲートの分散 (C#)」を参照してください。
関連トピック
タイトル | 説明 |
---|---|
ジェネリック インターフェイスの分散 (C#) | ジェネリック インターフェイスの共変性と反変性について説明し、.NET のバリアント ジェネリック インターフェイスの一覧を提供します。 |
バリアント ジェネリック インターフェイスの作成 (C#) | カスタムバリアントインターフェイスを作成する方法を示します。 |
ジェネリック コレクションのインターフェイスでの分散の使用 (C#) | IEnumerable<T>インターフェイスとIComparable<T> インターフェイスでの共変性と反変性のサポートがコードの再利用にどのように役立つかを示します。 |
デリゲートの分散 (C#) | ジェネリック デリゲートと非ジェネリック デリゲートの共変性と反変性について説明し、.NET のバリアント ジェネリック デリゲートの一覧を提供します。 |
デリゲートの変性の使用 (C#) | 非ジェネリック デリゲートで共変性と反変性のサポートを使用して、メソッドシグネチャとデリゲート型を照合する方法を示します。 |
Func と Action のジェネリックデリゲートにおける分散の利用方法 (C#) |
Func およびAction デリゲートでの共変性と反変性のサポートがコードの再利用にどのように役立つかを示します。 |
.NET