3

シーンリオを考えると:

public class Program
{
    static void Main()
    {
        object[] covarientArray= new A[] { new A() };
        object polymorphism = new A();
        object test = covarientArray[0];
        M(ref polymorphism);//fine up to here

        M(ref covarientArray[0]);//ArrayTypeMismatchException
    }

    static void M(ref object o) { Console.WriteLine(o); }
}
class A {}

ArrayTypeMisMatchの定義:

配列内に間違った型の要素を格納しようとしたときにスローされる例外。

この例外は、配列内に間違った型の要素を格納しようとするとスローされます。例えば:

A[] invalid = new A[1];
invalid[0] = "";//I can't store a type of string within an array of type of A

この例外はどのように発生しますか? refパラメータでメソッドを呼び出すときにストア操作を行っているのはなぜですか?

4

2 に答える 2

3

ref間違ったタイプの配列要素にを作成した場合にも、例外がスローされます。これは、例外テキストを読むだけでは明らかに不明確ですが、リンク先のページで間接的に非常に簡単に言及されています。

次のMicrosoft中間言語(MSIL)命令は、ArrayTypeMismatchExceptionをスローします。

ldelema

ldelema(ロード要素アドレス)は、配列要素への参照を作成するために使用される命令です。

理由については、すべての引数へのすべての割り当てで、型の実行時チェックを実行する必要がなくなります。 ref

于 2013-02-18T20:16:38.420 に答える
1

ref パラメーターを使用してメソッドを呼び出すときにストア操作を行っているのはなぜですか?

refパラメータへの引数として配列要素を提供すること、少なくとも潜在的にストア操作です。(ええ、再割り当てしないかもしれませんが、コンパイラ/ランタイムは必ずしもそれを認識していません)

Mメソッドの実装が次の場合を想像してください。

static void M(ref object o) 
{ 
    o = new B();
}

共変配列を次のobject[]ように入力すると、コンパイルして動作します。

object[] covariantArray= new object[] { new A() };
M(ref covariantArray[0]);
Console.WriteLine(covariantArray[0].GetType().Name); //B

実行され、最初の要素が B の新しいインスタンスに置き換えられます。もちろん、これは配列に対して完全に有効です。したがって、単純に次のように変更すると、次のようになります。object[]A[]

object[] covariantArray= new A[] { new A() };
M(ref covariantArray[0]); //ArrayTypeMismatchException
Console.WriteLine(covariantArray[0].GetType().Name);

潜在的に危険/壊滅的/犬は猫/アップはダウンの呼び出しMが処理される前に、例外をスローします。

もちろん、ref呼び出しを削除するかref、配列要素の代わりにローカル変数に対して実行すると、配列の内容をいじらないので、完全に正常に機能します。

@hvdの答えは、スローするための基本的なランタイムメカニズムを説明しているという点でおそらくより正しいですが、少なくともこれがそうである理由の実際的なデモンストレーションです。

于 2013-02-18T20:31:37.440 に答える