Почему Resharper говорит: "Ковариантное преобразование массива из строки [] в объект [] может вызвать исключение во время выполнения при операции записи" с помощью этого кода?
Этот код:
comboBoxMonth.Items.AddRange(UsageRptConstsAndUtils.months.ToArray());
public static List<String> months = new List<String>
{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
Превращает R # curmudgeon-like с жалобой: "Преобразование со-вариантного массива из строки [] в объект [] может вызвать исключение во время выполнения при операции записи".
Собственно, этот код работает отлично - поле со списком заполняется значениями месяца; что такое Resharper, и что я могу сделать, чтобы успокоить его сомнения?
Если просто, чтобы общий список мог содержать плохие данные, я не буду беспокоиться об этом - и если бы там была проблема, было бы достаточно легко найти проблему.
Ответы
Ответ 1
Метод comboBoxMonth.Items.AddRange
ожидает параметр object[]
. months.ToArray()
- string[]
. Приведение от string[]
до object[]
допустимо, но если метод пытается изменить элементы массива, вы получите ошибки во время выполнения. В этом случае это не так, поэтому вы можете игнорировать предупреждение.
Если это вас раздражает, вы можете использовать ToArray<object>()
comboBoxMonth.Items.AddRange(UsageRptConstsAndUtils.months.ToArray<object>());
Он вернет object[]
, и никакого приведения не потребуется.
Ответ 2
Пример демонстрации проблемы:
void Main()
{
Animal[] animals = new Girafee[2];
animals[0] = new Zebra();
}
public class Animal { }
public class Girafee : Animal { }
public class Zebra : Animal { }
Это вызовет ArrayTypeMismatchException
во время выполнения.
R # в основном намекает на возможную проблему того факта, что вы присваиваете string[]
object[]
, который полностью разрешен компилятором, но может привести к исключению во время выполнения, если объект, который имеет один и тот же базовый класс, присваивается массиву, который уже указывает на другой тип (как в моем примере, мы фактически указываем массив girafee). Соотношение между массивами нарушается в том смысле, что оно не дает вам безопасности во время компиляции с помощью генериков.
Эрик Липперт об этом говорит в Ковариация и контравариантность в С#, часть вторая: Ковариация массивов:
К сожалению, этот вид ковариации нарушен. это было добавлен в CLR, потому что Java требует этого, и дизайнеры CLR хотели чтобы поддерживать Java-подобные языки. Затем мы добавили его в С#, потому что он был в CLR. Это решение было довольно противоречивым в время, и я не очень доволен этим, но мы ничего не можем сделайте это сейчас.
Почему это сломано? Потому что всегда должно быть законно поставить Черепаху в массив животных. С ковариацией массива на языке и вы не можете гарантировать, что массив животных может принять Черепаха, потому что хранилище поддержки может быть массивом Жирафы.