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"
};

「string[] から object[] への共変配列変換により、書き込み操作で実行時例外が発生する可能性がある」という苦情で、R# curmudgeon のようになります。

実際、このコードは完全に機能します。コンボ ボックスには月の値が入力されています。Resharper は何について話しているのでしょうか? また、その疑いを和らげるために何ができるでしょうか?

ジェネリック リストに不正なデータが含まれている可能性があるという単純な理由であれば、心配する必要はありません。また、問題が発生した場合でも、問題を突き止めるのは簡単です。

4

2 に答える 2

49

このメソッドcomboBoxMonth.Items.AddRangeにはobject[]パラメーターが必要です。months.ToArray()ですstring[]string[]からへのキャスト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これにより、実行時にa がスローされます。

string[]R# は基本的に、 aを anに代入しているという事実の潜在的な問題を示唆していますがobject[]、これはコンパイラによって完全に許可されていますが、同じ基底クラスを共有するオブジェクトの場合、実行時例外が発生する可能性があります。は、すでに別の型を指している配列に割り当てられています (私の例のように、実際には girafee 配列を指しています)。配列の共分散は、ジェネリックで得られるコンパイル時の安全性を提供しないという意味で壊れています。

Eric Lippert は、C# の共分散と反分散、パート 2: 配列の共分散でこれについて語っています。

残念ながら、この特定の種類の共分散は破られています。Java がそれを必要とし、CLR 設計者が Java のような言語をサポートできるようにしたかったため、CLR に追加されました。CLR にあったので、それを C# に追加しました。この決定は当時非常に物議を醸し、私はあまり満足していませんが、今は何もできません.

なぜこれが壊れているのですか?カメを動物の配列に入れることは常に合法であるべきだからです。バッキング ストアが実際にはキリンの配列である可能性があるため、言語とランタイムの配列共分散では、動物の配列がタートルを受け入れることができることを保証できません。

于 2015-11-05T22:06:57.713 に答える