Spróbuję wyjaśnić odpowiedź Anthony'ego Pegrama.
Typ ogólny jest kowariantny dla argumentu typu, gdy zwraca wartości tego typu (np. Func<out TResult>Zwraca wystąpienia TResult, IEnumerable<out T>zwraca wystąpienia T). Oznacza to, że jeśli coś zwraca wystąpienia programu TDerived, możesz równie dobrze pracować z takimi wystąpieniami, jakby były TBase.
Typ ogólny jest kontrawariantny w przypadku niektórych argumentów typu, gdy akceptuje wartości tego typu (np. Action<in TArgument>Akceptuje wystąpienia TArgument). Oznacza to, że jeśli coś wymaga instancji TBase, możesz równie dobrze przejść w instancjach TDerived.
Wydaje się całkiem logiczne, że typy generyczne, które zarówno akceptują, jak i zwracają instancje pewnego typu (chyba że jest to zdefiniowane dwukrotnie w sygnaturze typu ogólnego, np. CoolList<TIn, TOut>) Nie są kowariantne ani kontrawariantne w odpowiednim argumencie typu. Na przykład Listjest zdefiniowany w .NET 4 jako List<T>, nie List<in T>lub List<out T>.
Niektóre przyczyny zgodności mogły spowodować, że firma Microsoft zignoruje ten argument i sprawi, że tablice będą kowariantne w ich argumencie typu wartości. Być może przeprowadzili analizę i odkryli, że większość ludzi używa tablic tylko tak, jakby były tylko do odczytu (to znaczy używają inicjatorów tablic tylko do zapisania niektórych danych w tablicy) i jako takie, zalety przeważają nad wadami spowodowanymi przez możliwe środowisko uruchomieniowe błędy, gdy ktoś spróbuje skorzystać z kowariancji podczas zapisu do tablicy. Dlatego jest to dozwolone, ale nie zalecane.
Jeśli chodzi o Twoje oryginalne pytanie, list.ToArray()tworzy nowe LinkLabel[]z wartościami skopiowanymi z oryginalnej listy i aby pozbyć się (rozsądnego) ostrzeżenia, musisz przejść Control[]do AddRange. list.ToArray<Control>()wykona zadanie: ToArray<TSource>przyjmuje IEnumerable<TSource>jako argument i zwraca TSource[]; List<LinkLabel>implementuje tylko do odczytu IEnumerable<out LinkLabel>, co dzięki IEnumerablekowariancji mogłoby zostać przekazane do metody akceptującej IEnumerable<Control>jako swój argument.
LinkLabel(typ specjalistyczny) doControl(typ podstawowy).