Я постараюсь уточнить ответ Энтони Пеграма.
Универсальный тип является ковариантным для некоторого аргумента типа, когда он возвращает значения указанного типа (например, Func<out TResult>возвращает экземпляры TResult, IEnumerable<out T>возвращает экземпляры T). То есть, если что-то возвращает экземпляры TDerived, вы также можете работать с такими экземплярами, как если бы они были TBase.
Универсальный тип является контравариантным для некоторого аргумента типа, когда он принимает значения указанного типа (например, Action<in TArgument>принимает экземпляры TArgument). То есть, если чему-то нужны экземпляры TBase, вы также можете передать экземпляры TDerived.
Кажется вполне логичным, что универсальные типы, которые одновременно принимают и возвращают экземпляры некоторого типа (если он не определен дважды в сигнатуре универсального типа, например CoolList<TIn, TOut>), не являются ковариантными и контравариантными для соответствующего аргумента типа. Например, Listв .NET 4 определено как List<T>not List<in T>или List<out T>.
Некоторые причины совместимости могли заставить Microsoft проигнорировать этот аргумент и сделать массивы ковариантными по аргументу типа значений. Возможно, они провели анализ и обнаружили, что большинство людей используют массивы только так, как если бы они были только для чтения (то есть они используют инициализаторы массива только для записи некоторых данных в массив), и, как таковые, преимущества перевешивают недостатки, вызванные возможной средой выполнения. ошибки, когда кто-то попытается использовать ковариацию при записи в массив. Следовательно, это разрешено, но не поощряется.
Что касается вашего исходного вопроса, list.ToArray()создается новый LinkLabel[]со значениями, скопированными из исходного списка, и, чтобы избавиться от (разумного) предупреждения, вам нужно перейти Control[]к AddRange. list.ToArray<Control>()выполнит свою работу: ToArray<TSource>принимает в IEnumerable<TSource>качестве аргумента и возвращает TSource[]; List<LinkLabel>реализует доступ только для чтения IEnumerable<out LinkLabel>, который, благодаря IEnumerableковариантности, может быть передан методу, принимающему в IEnumerable<Control>качестве аргумента.
LinkLabel(специализированный тип) кControl(базовый тип).