19

ここに議論のためのサンプルコードがあります(爬虫類は「動物であり、哺乳類は「動物でもある」と考えてください)

Animal[] reptiles = new Reptile[] 
    { new Reptile("lizard"), new Reptile("snake") };

Animal[] animals = new Animal[]
    { new Reptile("alligator"), new Mammal("dolphin") };

try
{
  Array.ConstrainedCopy(animals, 0, reptiles, 0, 2);
}
catch (ArrayTypeMismatchException atme)
{
  Console.WriteLine('[' + String.Join<Animal>(", ", reptiles) + ']');
}

このコードを実行すると、コメントとして ArrayTypeMismatchException が発生します

Array.ConstrainedCopy は、各配列要素のボックス化、ボックス化解除、拡張、またはキャストの形式を使用せずに、互換性が証明されている配列型でのみ機能します。配列の型を変更する (つまり、Derived[] を Base[] にコピーする) か、配列のクローンを作成するか、破損している可能性のあるコピー先配列を破棄するなど、Array.Copy のあまり強力でない信頼性コントラクトに対して CER で緩和戦略を使用します。

ただし、MSDNを見ると、このメソッドもInvalidCastException. を投げる条件InvalidCastExceptionは次のとおりです。

sourceArray の少なくとも 1 つの要素を destinationArray の型にキャストできません。

だから私は困惑しています、配列要素のキャストが決してできないと述べている場合、どうすればこのメソッドから InvalidCastException を取得できますか?

4

7 に答える 7

3

MSDNから(備考セクション):

sourceArray型は、destinationArrayと同じか、またはそこから派生している必要があります。それ以外の場合は、ArrayTypeMismatchException がスローされます。

あなたの例では、animals配列型は配列型と同じではないか、reptiles配列型から派生していません( anAnimalは a ではありませんReptile)。そのため、 anArrayTypeMismatchExcetionがスローされます。

InvalidCastException上記の条件と例の例外メッセージに基づいて、メソッドを呼び出すときに取得する方法はないと結論付けることができますArray.ConstrainedCopy。ドキュメントのバグです。

于 2013-09-24T20:54:18.310 に答える
3

ConstrainedCopyの実装は Array.Copy と同じですが、ReliabilityContractAttribute.
IL 逆アセンブラーで ConstrainedCopy を開くと、引数をスタックにロードして Array.Copy に渡すだけであることがわかります。
例外が示すようにArray.ConstrainedCopy、Array.Copy がスローしない特定のケースで例外をスローします。 配列をコピーする前にConstrainedCopy 検証します。

ここに画像の説明を入力

: 通常の Array.Copy メソッドは、バイト配列を int 配列にサイレントにコピーします。Array.ConstrainedCopy メソッドは代わりに例外をスローします。これにより、信頼性が向上します。

class Program
{
    static void Main()
    {
    byte[] original = new byte[10];
    original[0] = 1;

    int[] destination = new int[10];

    // This will work if you call Array.Copy instead.
    Array.ConstrainedCopy(original, 0, destination, 0, original.Length);
    }
}

ところで: Array.ConstrainedCopy では、拡大変換
を行う ことはできません。

結論:
Array.ConstrainedCopy メソッドは特定のコピーを許可しません。Array.Copy よりも識別力があります。また、例外をスローします。多くの場合、ConstrainedCopy は不要です。

質問について:
System.InvalidCastException : Array.ConstrainedCopy が Array.Copy を呼び出しているため、Array.Copy を呼び出すことでスローできる例外の 1 つです。しかし、検証の優先順位により、InvalidCastException が表示されることはありません。

于 2013-09-26T16:12:22.233 に答える