違い - c# 暗黙的に変換できません




なぜResharperは、このコードで "文字列[]からオブジェクト[]への共変種配列変換が実行時例外例外を引き起こす可能性がありますか? (2)

comboBoxMonth.Items.AddRangeメソッドは、 object[]パラメータを必要とします。 months.ToArray()string[]です。 string[]からobject[] string[]へのキャストは有効ですが、メソッドが配列の要素を変更しようとすると、実行時エラーが発生します。 この場合、警告は無視できます。

それはあなたを悩ませるなら、 ToArray<object>()使うことができます。

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

object[]が返され、キャストは必要ありません。

この質問には既に回答があります:

このコード:

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とは何ですか?私はその疑念を抱かせるために何ができますか?

単純にジェネリックリストに不正なデータが含まれている場合、私はそれについて心配することはありません。問題があった場合は、問題を追跡するだけで十分です。


この問題を示す例:

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

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

これは、実行時にArrayTypeMismatchExceptionをスローします。

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

Eric Lippert がC#での共分散とContravarianceでこれについて語っている、パート2:配列の共分散

残念ながら、このような種類の共分散は壊れています。 それはJavaがそれを必要とし、CLRデザイナーがJavaのような言語をサポートできるようにしたいので、CLRに追加されました。 その後、CLRにあったので、C#に追加しました。 この決定は、当時はかなり議論の余地がありましたが、私はそれについてはあまり幸せではありませんが、今はそれについて何もできません。

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