共変性と反変性 (C#)Covariance and Contravariance (C#)

C# では、共変性と反変性により、配列型、デリゲート型、およびジェネリック型引数の暗黙の参照変換が可能になります。In C#, covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments. 共変性は代入互換性を維持し、反変性はこれを反転させます。Covariance preserves assignment compatibility and contravariance reverses it.

次のコードでは、代入互換性、共変性、および反変性の違いについて説明します。The following code demonstrates the difference between assignment compatibility, covariance, and contravariance.

// 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;  

配列の共変性により、強い派生型の配列から弱い派生型の配列への暗黙の型変換が可能になります。Covariance for arrays enables implicit conversion of an array of a more derived type to an array of a less derived type. ただし、次のコード例に示すように、この操作はタイプ セーフではありません。But this operation is not type safe, as shown in the following code example.

object[] array = new String[10];  
// The following statement produces a run-time exception.  
// array[0] = 10;  

メソッド グループの共変性と反変性のサポートにより、メソッド シグネチャをデリゲート型と一致させることができます。Covariance and contravariance support for method groups allows for matching method signatures with delegate types. これにより、一致するシグネチャを持つメソッドだけでなく、デリゲート型で指定された型よりも強い派生型 (共変性) を返すメソッドや、弱い派生型 (反変性) のパラメーターを受け取るメソッドを、デリゲートに割り当てることができます。This enables you to assign to delegates not only methods that have matching signatures, but also methods that return more derived types (covariance) or that accept parameters that have less derived types (contravariance) than that specified by the delegate type. 詳細については、「デリゲートの分散 (C#)」および「デリゲートの分散の使用 (C#)」を参照してください。For more information, see Variance in Delegates (C#) and Using Variance in Delegates (C#).

次のコード例は、メソッド グループでの共変性と反変性のサポートを示しています。The following code example shows covariance and contravariance support for method groups.

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# でジェネリック インターフェイスと汎用デリゲートでの共変性と反変性がサポートされ、ジェネリック型パラメーターの暗黙の型変換が可能になっています。In .NET Framework 4 or newer C# supports covariance and contravariance in generic interfaces and delegates and allows for implicit conversion of generic type parameters. 詳細については、「ジェネリック インターフェイスの分散 (C#)」および「デリゲートの分散 (C#)」を参照してください。For more information, see Variance in Generic Interfaces (C#) and Variance in Delegates (C#).

次のコード例は、ジェネリック インターフェイスの暗黙の参照変換を示しています。The following code example shows implicit reference conversion for generic interfaces.

IEnumerable<String> strings = new List<String>();  
IEnumerable<Object> objects = strings;  

ジェネリック インターフェイスや汎用デリゲートは、そのジェネリック パラメーターが共変または反変として宣言されている場合、バリアントと呼ばれます。A generic interface or delegate is called variant if its generic parameters are declared covariant or contravariant. C# では、独自のバリアント インターフェイスおよびデリゲートを作成できます。C# enables you to create your own variant interfaces and delegates. 詳細については、「バリアント ジェネリック インターフェイスの作成 (C#)」および「デリゲートの分散 (C#)」を参照してください。For more information, see Creating Variant Generic Interfaces (C#) and Variance in Delegates (C#).

タイトルTitle 説明Description
ジェネリック インターフェイスの分散 (C#)Variance in Generic Interfaces (C#) ジェネリック インターフェイスでの共変性と反変性について説明し、.NET Framework でのバリアント ジェネリック インターフェイスの一覧を示します。Discusses covariance and contravariance in generic interfaces and provides a list of variant generic interfaces in the .NET Framework.
バリアント ジェネリック インターフェイスの作成 (C#)Creating Variant Generic Interfaces (C#) カスタムのバリアント インターフェイスを作成する方法を示します。Shows how to create custom variant interfaces.
ジェネリック コレクションに対するインターフェイスでの分散の使用 (C#)Using Variance in Interfaces for Generic Collections (C#) IEnumerable<T> および IComparable<T> インターフェイスでの共変性と反変性のサポートがコードの再利用にどのように役立つかを示します。Shows how covariance and contravariance support in the IEnumerable<T> and IComparable<T> interfaces can help you reuse code.
デリゲートの分散 (C#)Variance in Delegates (C#) 汎用および非汎用デリゲートでの共変性と反変性について説明し、.NET Framework でのバリアント汎用デリゲートの一覧を示します。Discusses covariance and contravariance in generic and non-generic delegates and provides a list of variant generic delegates in the .NET Framework.
デリゲートの分散の使用 (C#)Using Variance in Delegates (C#) 非汎用デリゲートでの共変性と反変性のサポートを使用して、メソッド シグネチャをデリゲート型に一致させる方法について説明します。Shows how to use covariance and contravariance support in non-generic delegates to match method signatures with delegate types.
Func および Action 汎用デリゲートでの分散の使用 (C#)Using Variance for Func and Action Generic Delegates (C#) Func および Action デリゲートでの共変性と反変性のサポートがコードの再利用にどのように役立つかを示します。Shows how covariance and contravariance support in the Func and Action delegates can help you reuse code.