次の方法で共有


共変性と反変性 (C#)

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デリゲートでの共変性と反変性のサポートがコードの再利用にどのように役立つかを示します。