Trataré de aclarar la respuesta de Anthony Pegram.
El tipo genérico es covariante en algún argumento de tipo cuando devuelve valores de dicho tipo (por Func<out TResult>
ejemplo TResult
, IEnumerable<out T>
devuelve instancias de , devuelve instancias de T
). Es decir, si algo devuelve instancias de TDerived
, también puede trabajar con instancias como si fueran de TBase
.
El tipo genérico es contravariante en algún argumento de tipo cuando acepta valores de dicho tipo (por ejemplo, Action<in TArgument>
acepta instancias de TArgument
). Es decir, si algo necesita instancias de TBase
, también puede pasar instancias de TDerived
.
Parece bastante lógico que los tipos genéricos que aceptan y devuelven instancias de algún tipo (a menos que se defina dos veces en la firma de tipo genérico, por ejemplo CoolList<TIn, TOut>
) no son covariantes ni contravariantes en el argumento de tipo correspondiente. Por ejemplo, List
se define en .NET 4 como List<T>
, no List<in T>
o List<out T>
.
Algunas razones de compatibilidad podrían haber causado que Microsoft ignore ese argumento y haga que las matrices sean covariantes en su argumento de tipo de valores. Tal vez realizaron un análisis y descubrieron que la mayoría de las personas solo usan matrices como si fueran de solo lectura (es decir, solo usan inicializadores de matriz para escribir algunos datos en una matriz) y, como tal, las ventajas superan las desventajas causadas por el posible tiempo de ejecución errores cuando alguien intentará hacer uso de la covarianza al escribir en la matriz. Por lo tanto, está permitido pero no es alentado.
En cuanto a su pregunta original, list.ToArray()
crea una nueva LinkLabel[]
con valores copiados de la lista original y, para deshacerse de la advertencia (razonable), deberá pasar Control[]
a AddRange
. list.ToArray<Control>()
hará el trabajo: ToArray<TSource>
acepta IEnumerable<TSource>
como argumento y devuelve TSource[]
; List<LinkLabel>
implementa solo lectura IEnumerable<out LinkLabel>
, que, gracias a la IEnumerable
covarianza, podría pasarse al método que acepta IEnumerable<Control>
como argumento.
LinkLabel
(tipo especializado) aControl
(tipo base).