Подтвердить что ты не робот

Почему 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, и что я могу сделать, чтобы успокоить его сомнения?

Если просто, чтобы общий список мог содержать плохие данные, я не буду беспокоиться об этом - и если бы там была проблема, было бы достаточно легко найти проблему.

4b9b3361

Ответ 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. Это решение было довольно противоречивым в время, и я не очень доволен этим, но мы ничего не можем сделайте это сейчас.

Почему это сломано? Потому что всегда должно быть законно поставить Черепаху в массив животных. С ковариацией массива на языке и вы не можете гарантировать, что массив животных может принять Черепаха, потому что хранилище поддержки может быть массивом Жирафы.