質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

60889閲覧

ListにAddする再、何故か全てのデータがAddしたデータに上書きされてしまいます。

GiveAHand

総合スコア286

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

1グッド

1クリップ

投稿2016/06/18 13:41

C#でプログラムを作成しています。

C#

1// サンプルデータ格納クラス 2private class data_sample 3{ 4 public string data1 { get; set; } 5 public string data2 { get; set; } 6} 7 8List<data_test> SampleList = new List<data_test>();

このように定義したリストに対して、

C#

1data_sample sample; 2sample = new data_sample(); 3 4//データセット 5sample.data1 = (ここになんらかのデータをセット); 6sample.data2 = (ここになんらかのデータをセット); 7 8//リストに追加 9SampleList.Add(sample);

このようにデータをセットしているのですが、何故か追加するたびに、全てのデータが、最後に追加したデータに上書きされたようになってしまいます。

例えば、最初に

C#

1//データセット 2sample.data1 = "aaa"; 3sample.data2 = "111"; 4 5//リストに追加 6SampleList.Add(sample);

このようにデータをセットすると、SampleListには、data1に"aaa"、data2に"111"がセットされるのですが、その後、

C#

1//データセット 2sample.data1 = "bbb"; 3sample.data2 = "222"; 4 5//リストに追加 6SampleList.Add(sample);

とすると、SampleListの配列は2つになるのですが、data1は2つとも"bbb"、data2は2つとも"222"になってしまい、最初にAddした、"aaa"と"111"は無くなってしまいます。

その後、例えばもうひとつデータを追加して、

C#

1//データセット 2sample.data1 = "ccc"; 3sample.data2 = "333"; 4 5//リストに追加 6SampleList.Add(sample);

とすれば、配列数は3つになりますが、データは3つとも最後に追加したデータになってしまいます。

なぜこのようになってしまうのか、それがわかりません。

どうして、このような事になってしまうのでしょうか?

sheephuman👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

こんにちは。

C#のクラスは参照型ですので単純に代入した場合、単にそのアドレスが代入されるだけです。
List<T>のaddは代入と同じ動作をするようですので、単にsampleのアドレスがリストへ追加されるだけなのです。

従って、SampleList.add(sample);を3回実行した場合、sampleのアドレスを3つSampleListへ追加されます。つまり、全部同じインスタンスへの参照(ポインタ)が設定されます。
従って、SampleListの要素を全て表示した場合、最後にsampleに設定した値が常に表示されます。

MSDNのサンプルのように、newしたものをadd()しましょう。それにより異なるdata_sampleのインスタンスが追加されます。


【余談ですが】
C#は、Javaと同じくポインタを意識しないで済む文法になっていますが、実装はポインタを使ってますので、ポインタを理解していないと今回のようなトラブルを解決することが厳しいです。

投稿2016/06/18 14:02

編集2016/06/18 14:02
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GiveAHand

2016/06/18 14:06

Chironian様 おぉ!これはわかりやすい説明!!! なるほど、そういう事なんですね!!! ありがとうございました! よく理解できました!
guest

0

こんにちは。

もう少しコードの前後を精査する必要はありますが、
最も単純な可能性としてはAddしたインスタンスsampleが同一であることでしょうか。
毎回newしたインスタンスをAddしても発生しますか?

投稿2016/06/18 13:47

Tak1wa

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GiveAHand

2016/06/18 14:04

Tak1wa様 毎回newしたら、うまくいきました! ありがとうございました!
guest

0

上記プログラムですと、sampleがすべて同じインスタンスを参照してしまっているかもしれません。

都度インスタンスを生成してListにセットするとどうでしょうか?

c#

1data_sample sample1 = new data_sample(); 2sample1.data1 = "aaa"; 3sample1.data2 = "111"; 4 5//リストに追加 6SampleList.Add(sample1); 7 8 9data_sample sample2 = new data_sample(); 10sample2.data1 = "bbb"; 11sample2.data2 = "222"; 12 13//リストに追加 14SampleList.Add(sample2); 15

投稿2016/06/18 13:50

takyafumin

総合スコア2335

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GiveAHand

2016/06/18 14:03

takafumin様 上記のやり方で、うまくいきました! ありがとうございました!
takyafumin

2016/06/18 14:07

動いたようでよかったです。 ただ、この事象は「どうしてそうなるのか?」をきちんと理解しておくことをお勧めします。 Chironianさまの回答をよく読むと理解の助けになるかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問