C#の値/オブジェクトはいつコピーされ、その参照はいつコピーされるのですか?
質問
参照したいオブジェクトがコピーされたり、コピーしたいオブジェクトが参照されたりして、何度も同じ問題が発生します。これは、=演算子を使用したときに起こります。
たとえば、私がオブジェクトを別のフォームに送信している場合、すなわち、:
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.formObject
と
myObject
の同じインスタンスを参照しています。
SomeObject
- 例えば、二人の人間が別々の紙を持ち、それぞれに同じ住所が書かれているようなものです。1 枚の紙に書かれた住所に行き、家を赤く塗った後、2 枚目の紙に書かれた住所に行くと、赤い家が見えてきます。
あなたが提供した型は不変なので、"and then modify the object in the form"が何を意味するのか明らかでありません。オブジェクト自体を変更する方法はありません。変更できるのは
myForm.formObject
の別のインスタンスを参照するように
SomeObject
のインスタンスを参照することができますが、それは一枚の紙の上に住所を走り書きして、代わりに別の住所を書くようなものです。それでは、もう一枚の紙に書かれていることは変わりません。
もしあなたが、短いけれども 完全 プログラム (理想的にはコンソール アプリケーションで、物事を短くシンプルに保つために) を提供できれば、具体的な用語で物事を話すことが容易になるでしょう。
関連
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】ORA-01008: すべての変数がバインドされていません。これらはバインドされています。
-
[解決済み】リソースの読み込みに失敗した:ステータス500(内部サーバーエラー)のサーバーの応答)
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み] async」と「await」の使い方とタイミング
-
[解決済み] LINQで.Firstと.FirstOrDefaultを使用するタイミングは?
-
[解決済み】PHPの配列は、値としてコピーされますか、それとも新しい変数への参照としてコピーされますか、そして関数に渡されたとき?
-
[解決済み] C#でrefを使うときと使わないとき
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】C#で四捨五入する方法
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み] [Solved] アセンブリ System.Web.Extensions dll はどこにありますか?
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】データが存在しないのに読み込もうとする試みが無効である