此代码:
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,“从字符串[]到对象[]的共变量数组转换可能导致写入操作的运行时异常”。
实际上,此代码完美无缺 - 组合框中填充了月份值;什么是Resharper,我该怎么做才能缓解它的疑虑?
如果只是通用列表可能包含错误数据,我不会担心 - 如果遇到问题,那么追踪问题就很容易了。
答案 0 :(得分:30)
方法comboBoxMonth.Items.AddRange
需要object[]
参数。 months.ToArray()
是string[]
。从string[]
到object[]
的强制转换有效,但如果该方法尝试修改数组的元素,则会出现运行时错误。在这种情况下它没有,所以你可以忽略警告。
如果它让您烦恼,可以使用ToArray<object>()
comboBoxMonth.Items.AddRange(UsageRptConstsAndUtils.months.ToArray<object>());
它将返回object[]
,不需要演员。
答案 1 :(得分:15)
证明问题的一个例子:
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数组)。数组协方差被打破,意思是它不能为您提供泛型的编译时安全性。
Eric Lippert在Covariance and Contravariance in C#, Part Two: Array Covariance中讨论了这个问题:
不幸的是,这种特殊的协方差被打破了。它是 添加到CLR,因为Java需要它和CLR设计者想要的 能够支持类似Java的语言。然后我们将其添加到 C#因为它在CLR中。这个决定很有争议 时间和我对此并不是很满意,但我们无能为力 现在就做。
为什么会这样?因为放一只乌龟应该是合法的 成一群动物。使用语言中的数组协方差和 运行时你无法保证动物数组可以接受 龟,因为后备存储实际上可能是一个数组 长颈鹿。