1. ホーム
  2. c#

C#の値/オブジェクトはいつコピーされ、その参照はいつコピーされるのですか?

2023-10-14 14:37:51

質問

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

たとえば、私がオブジェクトを別のフォームに送信している場合、すなわち、:

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

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

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

...そして anotherObject , myObject も同様に修正されます。

最も厄介なケースは、定義されたオブジェクトの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番目の例のようにメンバー変数をコピーするときなど)において、オブジェクトはいつコピーされ、いつ参照されるのでしょうか。

どのように解決するのですか?

この種の質問に正確に答えるには、言葉を注意深く選ぶことに膨大な時間を費やさなければ難しいです。

私はいくつかの記事でそうしてきましたので、役に立つと思います。

もちろん、この記事が完璧だというわけではありません - とんでもないです - が、できる限り分かりやすくなるように努めました。

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

具体的な例を見てみると

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

これはつまり myForm.formObjectmyObject の同じインスタンスを参照しています。 SomeObject - 例えば、二人の人間が別々の紙を持ち、それぞれに同じ住所が書かれているようなものです。1 枚の紙に書かれた住所に行き、家を赤く塗った後、2 枚目の紙に書かれた住所に行くと、赤い家が見えてきます。

あなたが提供した型は不変なので、"and then modify the object in the form"が何を意味するのか明らかでありません。オブジェクト自体を変更する方法はありません。変更できるのは myForm.formObject の別のインスタンスを参照するように SomeObject のインスタンスを参照することができますが、それは一枚の紙の上に住所を走り書きして、代わりに別の住所を書くようなものです。それでは、もう一枚の紙に書かれていることは変わりません。

もしあなたが、短いけれども 完全 プログラム (理想的にはコンソール アプリケーションで、物事を短くシンプルに保つために) を提供できれば、具体的な用語で物事を話すことが容易になるでしょう。