0

.NETの関数に配列を渡して何かをしようとしていますが、少し混乱しています。配列は参照型であるため、関数に渡された配列に加えられた変更は、関数の外部に表示されます。例

static void Main(string[] args)
{
    byte[] arr = new byte[] { 1,2, 3, 4, 5 };    
    Console.WriteLine(string.Join("", arr));        //console output: 12345
    doSomething(arr);
    Console.WriteLine(string.Join("", arr));        //console output: 52341
}
static void doSomething(byte[] array)
{
    byte tmp = array[0];
    array[0] = array[array.Length - 1];
    array[array.Length - 1] = tmp;
}

したがって、「ref」キーワードを使用した場合とまったく同じように機能します(同じコンソール出力)

doSomething(ref arr);  for static void doSomething(ref byte[] array)

ただし、関数に次の行を追加すると、次のようになります。

array = (new byte[] { 1 }).Concat(array).ToArray(); //size of array is changed

結果は異なります。

12345
52341// "ref" keyword is not used

12345
152341 "ref" keyword is used

結果が異なる理由を誰かに説明してもらえますか?

4

2 に答える 2

2

値型変数は、値を含む変数です。arrは、メモリ内のbyte[]のインスタンスを指すオブジェクト変数です。それを値でメソッドdoSomethingに渡すときは、メモリ内のbyte[]のインスタンスへのポインタを渡します。このようにして、arrとarrayの両方が、メモリ内のbyte[]の同じインスタンスを指します。DoSomethingがarrとarrayの両方が指しているbyte[]のインスタンスを変更した場合、それはまだメモリ内の同じ場所を指しているため、実際には変数arrを変更しません。ただし、arrはまだメモリ内の同じ場所を指しており、その場所のインスタンスが更新されているため、arrは変更を「見る」ことができます。

Concatを呼び出すと、メモリ内の別の場所にbyte []の新しいインスタンスが生成され、変数配列がメモリ内の新しいインスタンスに配置されます。byte []の古いインスタンスはまだ存在しており、arrはまだそれを指しています。

変数arrをrefで渡す場合、配列が指している場所を変更すると、 arrが指している場所にも影響します。refによって渡されない場合、DoSomethingは、 arrが指すメモリ内のbyte []のインスタンスのみを変更できますが、 arrが指す場所は変更できません。

そのため、参照によるオブジェクトの受け渡しと値によるオブジェクトの受け渡しには違いがあります。

于 2012-11-30T22:26:01.597 に答える
0

キーワードなしでメソッドに渡されたパラメータの場合-ローカル変数が作成され、元のパラメータRefのコピーを表します。したがって、参照型変数を渡した場合、これは実際には、ADDRなどのアドレスを指すInt32参照です。次に、メソッドでこの変数のコピーが作成され、元のパラメーターから完全にバインドされていません()。ただし、それでもメモリ内の同じアドレスを指しているため、基になる元のデータを変更できます。また、参照値のローカルコピーを割り当てて参照値自体を変更すると変更されますが、この変更はメソッドで渡される元の参照には影響しません。arrarr= new ...

new()元の参照とメソッドで作成された新しい参照を-useで「バインド」する場合は、「参照を参照によって/参照に渡したい」とRef指定します。Ref

次の行の後:

array = (new byte[] { 1 }).Concat(array).ToArray();
  • パラメータの場合Ref:参照が変更されましたが、参照によって渡されるため(Ref)-元の参照も影響を受けます
  • デフォルトのパラメータを渡す場合:参照のローカルコピーは変更されますが、元のコピーは影響を受けないため、新しく作成された配列を指す新しい参照を取得します
于 2012-11-30T22:43:18.600 に答える