Kowariancja i kontrawariancja (C#)

W języku C# kowariancja i kontrawariancja umożliwiają niejawną konwersję odwołania dla typów tablic, typów delegatów i argumentów typu ogólnego. Kowariancja zachowuje zgodność przypisań i kontrawariancję odwraca ją.

Poniższy kod przedstawia różnicę między zgodnością przypisań, kowariancją i kontrawariancją.

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

Kowariancja dla tablic umożliwia niejawną konwersję tablicy bardziej pochodnego typu na tablicę mniej pochodnego typu. Jednak ta operacja nie jest bezpieczna, jak pokazano w poniższym przykładzie kodu.

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

Obsługa kowariancji i kontrawariancji dla grup metod umożliwia dopasowywanie podpisów metody z typami delegatów. Dzięki temu można przypisać do delegatów nie tylko metody, które mają zgodne podpisy, ale także metody, które zwracają więcej typów pochodnych (kowariancja) lub które akceptują parametry, które mają mniej pochodne typy (kontrawariancja) niż określone przez typ delegata. Aby uzyskać więcej informacji, zobacz Wariancja w delegatach (C#) i Używanie wariancji w delegatach (C#).

W poniższym przykładzie kodu przedstawiono współwariancję i obsługę kontrawariancji dla grup metod.

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

W .NET Framework 4 i nowszych wersjach język C# obsługuje kowariancję i kontrawariancję w interfejsach ogólnych i delegatach oraz umożliwia niejawną konwersję parametrów typu ogólnego. Aby uzyskać więcej informacji, zobacz Variance in Generic Interfaces (C#) and Variance in Delegates (C#) (Wariancja w interfejsach ogólnych (C#) i Variance in Delegates (C#).

Poniższy przykład kodu przedstawia niejawną konwersję odwołania dla interfejsów ogólnych.

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

Ogólny interfejs lub delegat jest nazywany wariantem , jeśli jego parametry ogólne są deklarowane kowariantne lub kontrawariantne. Język C# umożliwia tworzenie własnych interfejsów wariantów i delegatów. Aby uzyskać więcej informacji, zobacz Creating Variant Generic Interfaces (C#) and Variance in Delegates (C#)( Tworzenie wariantów interfejsów ogólnych (C#) i Variance in Delegates (C#).

Tytuł Opis
Wariancja w interfejsach ogólnych (C#) Omówienie kowariancji i kontrawariancji w interfejsach ogólnych i zawiera listę wariantów interfejsów ogólnych na platformie .NET.
Tworzenie wariantów interfejsów ogólnych (C#) Przedstawia sposób tworzenia niestandardowych interfejsów wariantów.
Używanie wariancji w interfejsach dla kolekcji ogólnych (C#) Pokazuje, jak kowariancja i kontrawariancja obsługi w IEnumerable<T> interfejsach i IComparable<T> mogą pomóc w ponownym użyciu kodu.
Wariancja w delegatach (C#) Omówienie kowariancji i kontrawariancji w delegatach ogólnych i niegenerycznych oraz zawiera listę wariantów delegatów ogólnych na platformie .NET.
Używanie wariancji w delegatach (C#) Pokazuje, jak używać obsługi kowariancji i kontrawariancji w delegatach innych niż ogólne w celu dopasowania podpisów metody do typów delegatów.
Używanie wariancji dla delegatów ogólnych Func i Action (C#) Pokazuje, jak kowariancja i kontrawariancja w obiekcie Func i Action delegatów mogą pomóc w ponownym użyciu kodu.