Vou tentar esclarecer a resposta de Anthony Pegram.
O tipo genérico é covariante em algum argumento de tipo quando retorna valores desse tipo (por exemplo, Func<out TResult>
retorna instâncias de TResult
, IEnumerable<out T>
retorna instâncias de T
). Ou seja, se algo retornar instâncias de TDerived
, você também poderá trabalhar com instâncias como se fossem de TBase
.
O tipo genérico é contravariante em algum argumento de tipo quando aceita valores desse tipo (por exemplo, Action<in TArgument>
aceita instâncias de TArgument
). Ou seja, se algo precisa de instâncias de TBase
, você também pode passar em instâncias de TDerived
.
Parece bastante lógico que tipos genéricos que aceitam e retornam instâncias de algum tipo (a menos que sejam definidos duas vezes na assinatura de tipo genérica, por exemplo CoolList<TIn, TOut>
) não sejam covariantes nem contravariantes no argumento de tipo correspondente. Por exemplo, List
é definido no .NET 4 como List<T>
, não List<in T>
ou List<out T>
.
Alguns motivos de compatibilidade podem ter causado a Microsoft a ignorar esse argumento e tornar as matrizes covariantes em seu argumento de tipo de valores. Talvez eles tenham realizado uma análise e tenham descoberto que a maioria das pessoas usa apenas matrizes como se fossem somente leitura (ou seja, elas usam apenas inicializadores de matriz para gravar alguns dados em uma matriz) e, como tal, as vantagens superam as desvantagens causadas por um possível tempo de execução erros quando alguém tenta usar covariância ao escrever na matriz. Por isso, é permitido, mas não incentivado.
Quanto à sua pergunta original, list.ToArray()
cria uma nova LinkLabel[]
com os valores copiados da lista original e, para se livrar do aviso (razoável), você precisará passar Control[]
para AddRange
. list.ToArray<Control>()
fará o trabalho: ToArray<TSource>
aceita IEnumerable<TSource>
como argumento e retorna TSource[]
; List<LinkLabel>
implementa somente leitura IEnumerable<out LinkLabel>
, que, graças à IEnumerable
covariância, pode ser passado para o método que aceita IEnumerable<Control>
como argumento.
LinkLabel
(tipo especializado) paraControl
(tipo base).