74

参照したいオブジェクトがコピーされている場所、またはコピーしたいオブジェクトが参照されている場所で、同じ問題が何度も発生します。これは、= 演算子を使用したときに発生します。

たとえば、オブジェクトを別のフォームに送信している場合、つまり:

SomeForm myForm = new SomeForm();
SomeObject myObject = new SomeObject();
myForm.formObject = myObject;

...そしてフォーム内のオブジェクトを変更しても、元のオブジェクトは変更されません。オブジェクトがコピーされ、参照されていないかのようです。しかし、私がこれを行うとき:

SomeObject myObject = new SomeObject();
SomeObject anotherObject = new SomeObject();
anotherObject = myObject;

...そして変更しanotherObjectmyObject同様に変更されます。

最も厄介なケースは、定義済みのオブジェクトの 1 つを複製しようとする場合です。

public class SomeObject
{
    double value1, value2;

    //default constructor here

    public SomeObject(val1, val2)
    {
        value1 = val1;
        value2 = val2;
    }

    public void Clone(SomeObject thingToCopy)
    {
        this.value1 = thingToCopy.value1;
        this.value2 = thingToCopy.value2;
    }
}

私がこれをするとき...

SomeObject obj1 = new SomeObject(1, 2);
SomeObject obj2 = new SomeObject();
obj2.Clone(obj1);

...obj1が参照され、すべての変更が変更されobj2ますobj1

などのシステム オブジェクトint, double, stringは、上記の clone メソッドの場合を除いて、常にコピーされているようです。

私の質問は、関数でのキーワードの使用を考慮せずにref、オブジェクトがいつコピーされ、いつオブジェクトが参照されるのかということです (つまり、関数に渡すとき、他のオブジェクトとして設定するとき) (上記の最初の 2 つの例)、3 番目の例のようにメンバー変数をコピーする場合など)?

4

3 に答える 3

56

言葉を慎重に選ぶのに非常に多くの時間を費やさずに、この種の質問に正確に答えることは困難です。

私はあなたが役に立つと思うかもしれないいくつかの記事でそうしました:

もちろん、記事が完璧だと言っているわけではありませんが、できる限り明確にするように努めました。

重要なことの1つは、2つの概念(パラメーターの受け渡しと参照型と値型)を頭の中で分離することだと思います。

特定の例を見るには:

SomeForm myForm = new SomeForm();
SomeObject myObject = new SomeObject();
myForm.formObject = myObject;

これは、同じインスタンスを参照myForm.formObjectすることを意味します。たとえば、 2人が別々の紙を持ち、それぞれに同じ住所が書かれている場合などです。一枚の紙の住所に行って家を赤く塗ってから、二枚目の紙の住所に行くと、赤い家が見えます。myObjectSomeObject

指定した型は不変であるため、「フォーム内のオブジェクトを変更する」とはどういう意味かは明確ではありません。オブジェクト自体を変更する方法はありません。myForm.formObjectの別のインスタンスを参照するように変更できますがSomeObject、それは1枚の紙に住所を書き留めて、代わりに別の住所を書き込むようなものです。それは他の紙に書かれていることを変えることはありません。

動作が理解できない短いが完全なプログラム(理想的には、物事を短く単純にするためのコンソールアプリケーション)を提供できれば、具体的な言葉で物事について話すのが簡単になります。

于 2010-12-03T17:16:45.810 に答える
9

Hi Mike 構造体やその他のプリミティブ型など、ValueType から派生するすべてのオブジェクトは値型です。つまり、変数に割り当てたり、メソッド パラメーターとして渡したりするたびにコピーされます。他の型は参照型です。つまり、参照型を変数に割り当てると、その値ではなく、メモリ空間内のアドレスが変数に割り当てられます。また、ref キーワードを使用して、値の型を参照として渡すことができることに注意してください。構文は次のとおりです

public void MyMethod(ref int a) { a = 25 }
int i = 20;
MyMethod(ref i); //Now i get's updated to 25.

それが役に立てば幸い :)

于 2010-12-03T17:03:44.757 に答える
1

オブジェクトの複製に関して、あるオブジェクトから別のオブジェクトにコピーする値が参照型である場合、元のオブジェクトの値を変更すると、コピーされたオブジェクトの値に影響します (同じオブジェクトへの参照であるため)。

参照型であるプロパティを持つオブジェクトを複製する必要がある場合は、それらの型を複製可能にするか、必要に応じて新しいインスタンスをインスタンス化して手動でコピーする必要があります。

IClonableインターフェイスの使用を検討してください。ただし、これは最善の解決策ではありません。

于 2010-12-03T17:04:38.797 に答える