Проще говоря: универсальная дисперсия в .NET 4 не поддерживает дисперсию для аргументов типа, являющихся типами значений.
Причина, по которой это может работать для ссылочных типов, заключается в том, что, как только CLR решит, что он знает универсальныепреобразование безопасно, оно может обрабатывать все ссылочные значения одинаково - они имеют одинаковое представление внутри.Не требуется фактическое преобразование, чтобы превратить string
ссылку в object
ссылку, или наоборот, если вы знаете, что это определенно ссылка на строку - это в основном те же самые биты.Таким образом, сгенерированный нативный код может просто обращаться со ссылками как с ссылками, радуясь тому, что правила, связанные с дисперсией, гарантируют, что на уровне безопасности типов ничего не произойдет, и не выполняют никаких преобразований для самих значений.
То, что не истина для типов значений, или для ссылочных типов, где преобразование не является "ссылочным преобразованием" (т. Е. Сохраняющим представление).Вот почему вы не можете написать IEnumerable<XName> names = new List<string>();
кстати ...