Bagikan melalui


Kovariansi dan Kontravarian (C#)

Dalam C#, kovariansi dan kontravariansi memungkinkan konversi referensi implisit untuk jenis array, jenis delegasi, dan argumen jenis generik. Kovariansi mempertahankan kompatibilitas penugasan dan kontravariansi membalikkannya.

Kode berikut menunjukkan perbedaan antara kompatibilitas penugasan, kovariansi, dan kontravariansi.

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

Kovariansi untuk array memungkinkan konversi implisit dari array dari jenis yang lebih diturunkan ke array dari jenis yang kurang diturunkan. Tetapi operasi ini bukan merupakan jenis aman, seperti yang ditunjukkan dalam contoh kode berikut.

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

Dukungan kovariansi dan kontravariansi untuk grup metode memungkinkan pencocokan tanda tangan metode dengan jenis delegasi. Ini memungkinkan Anda menetapkan pada delegasi bukan hanya metode yang memiliki tanda tangan yang cocok, tetapi juga metode yang mengembalikan lebih banyak jenis turunan (kovariansi) atau yang menerima parameter yang memiliki jenis turunan yang lebih sedikit (kontravariansi) daripada yang ditentukan oleh jenis delegasi. Untuk informasi selengkapnya, lihat Varians di Delegasi (C#) dan Menggunakan Varians di Delegasi (C#).

Contoh kode berikut menunjukkan dukungan kovariansi dan kontravariansi untuk grup metode.

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

Dalam .NET Framework 4 dan versi yang lebih baru, C# mendukung kovariansi dan kontravariansi dalam antarmuka generik dan delegasi dan memungkinkan konversi implisit parameter jenis generik. Untuk informasi selengkapnya, lihat Varians di Antarmuka Generik (C#) dan Varians di Delegasi (C#).

Contoh kode berikut menunjukkan konversi referensi implisit untuk antarmuka generik.

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

Antarmuka atau delegasi generik disebut varian jika parameter generiknya dinyatakan kovarian atau kontravarian. C# memungkinkan Anda membuat antarmuka dan delegasi varian Anda sendiri. Untuk informasi selengkapnya, lihat Membuat Varian Antarmuka Generik (C#) dan Varians di Delegasi (C#).

Judul Deskripsi
Variansi dalam Antarmuka Generik (C#) Membahas kovariansi dan kontravariansi dalam antarmuka generik dan menyediakan daftar antarmuka generik varian di .NET.
Membuat Varian Antarmuka Generik (C#) Memperlihatkan cara membuat antarmuka varian kustom.
Menggunakan Variansi dalam Antarmuka untuk Koleksi Generik (C#) Menunjukkan bagaimana dukungan kovariansi dan kontravariansi di antarmuka IEnumerable<T> dan IComparable<T> dapat membantu Anda menggunakan kembali kode.
Varian dalam Delegasi (C#) Membahas kovariansi dan kontravariansi dalam delegasi generik dan non-generik dan menyediakan daftar delegasi generik varian di .NET.
Menggunakan Variansi dalam Delegasi (C#) Memperlihatkan cara menggunakan dukungan kovariansi dan kontravariansi dalam delegasi non-generik untuk mencocokkan tanda tangan metode dengan jenis delegasi.
Menggunakan Variansi untuk Delegasi Generik Fungsi dan Tindakan (C#) Menunjukkan bagaimana dukungan kovariansi dan kontravariansi dalam delegasi Func dan Action dapat membantu Anda menggunakan kembali kode.