27

这段代码:

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 是关于什么的,我能做些什么来减轻它的疑虑?

如果只是通用列表可能包含错误数据,我不会担心 - 如果有问题,追踪问题很容易。

4

2 回答 2

49

该方法comboBoxMonth.Items.AddRange需要一个object[]参数。months.ToArray()string[]。从string[]to的强制转换object[]是有效的,但如果该方法试图修改数组的元素,您将得到运行时错误。在这种情况下它不会,因此您可以忽略警告。

如果它让您烦恼,您可以使用ToArray<object>()

comboBoxMonth.Items.AddRange(UsageRptConstsAndUtils.months.ToArray<object>());

它将返回object[]并且不需要演员表。

于 2015-11-05T22:08:36.900 回答
18

演示问题的示例:

void Main()
{
    Animal[] animals = new Girafee[2];
    animals[0] = new Zebra();
}

public class Animal { }
public class Girafee : Animal { }
public class Zebra : Animal { }

ArrayTypeMismatchException这将在运行时抛出一个。

R# 基本上是在向您暗示一个可能的问题,即您将 a 分配给 a string[]object[]这是编译器完全允许的,但如果对象共享相同的基类,则可能导致运行时异常,分配给已经指向不同类型的数组(在我的示例中,我们实际上指向了一个 girafee 数组)。数组协方差被破坏的意思是它不能为您提供泛型所获得的编译时安全性。

Eric Lippert在 C# 中的协方差和逆变,第二部分:数组协方差中谈到了这一点:

不幸的是,这种特殊的协方差被破坏了。它被添加到 CLR 是因为 Java 需要它并且 CLR 设计者希望能够支持类似 Java 的语言。然后我们将它添加到 C# 中,因为它在 CLR 中。这个决定在当时颇有争议,我对此并不十分高兴,但现在我们对此无能为力。

为什么这个坏了?因为将 Turtle 放入 Animals 数组中应该始终是合法的。使用语言和运行时中的数组协方差,您不能保证 Animals 数组可以接受 Turtle,因为后备存储实际上可能是 Giraffes 数组。

于 2015-11-05T22:06:57.713 回答