Udostępnij za pomocą


Kowariancja i kontrawariancja (C#)

W języku C# kowariancja i kontrawariancja umożliwiają niejawną konwersję referencji dla typów danych tablicowych, typów delegatów i argumentów typu ogólnego. Kowariancja zachowuje zgodność przypisań, a kontrawariancja ją odwraca.

Poniższy kod demonstruje różnicę między zgodnością przypisania, 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 wariancji i kontrawariancji dla grup metod umożliwia dopasowywanie podpisów metod z typami delegatów. Dzięki temu można przypisać do delegatów nie tylko metody, które mają pasujące podpisy, ale także metody zwracające bardziej pochodne typy (kowariancja) lub takie, które akceptują parametry o mniej pochodnych typach (kontrawariancja) niż te określone przez typ delegata. Aby uzyskać więcej informacji, zobacz Wariancja w delegatach (C#) i Używanie wariancji w delegatach (C#).

Poniższy przykład kodu przedstawia obsługę kowariancji i 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 programie .NET Framework 4 i nowszych wersjach język C# obsługuje wariancję i kontrawariancję w interfejsach ogólnych i delegatach oraz umożliwia niejawną konwersję parametrów typu ogólnego. Aby uzyskać więcej informacji, zobacz Wariancję w interfejsach ogólnych (C#) i Wariancję w delegatach (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;  

Interfejs ogólny 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 wariantowych 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 wariancji w delegatach (C#).

Nazwa Opis
Wariancja w interfejsach ogólnych (C#) Omówienie kowariancji i kontrawariancji w interfejsach ogólnych oraz zawiera listę wariantów interfejsów ogólnych na platformie .NET.
Tworzenie wariantów interfejsów ogólnych (C#) Pokazuje, jak tworzyć niestandardowe interfejsy wariantów.
Używanie wariancji w interfejsach dla kolekcji ogólnych (C#) Pokazuje, jak obsługa kowariancji i kontrawariancji w interfejsach IEnumerable<T> i IComparable<T> może pomóc w ponownym użyciu kodu.
Wariancja w delegatach (C#) Omawia kowariancję i kontrawariancję w delegatach generycznych i niegenerycznych oraz przedstawia listę wariantowych delegatów generycznych na platformie .NET.
Używanie wariancji w delegatach (C#) Pokazuje, jak korzystać z obsługi kowariancji i kontrawariancji w delegatach nieogólnych, aby dopasować podpisy metod do typów delegatów.
Używanie wariancji dla delegatów ogólnych Func i Action (C#) Pokazuje, jak obsługa kowariancji i kontrawariancji w delegatach Func i Action może pomóc w ponownym użyciu kodu.