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

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

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

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

解決済

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

GiveAHand
GiveAHand

総合スコア286

C#

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

3回答

1グッド

1クリップ

50084閲覧

投稿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👍を押しています

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答3

5

ベストアンサー

こんにちは。

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

総合スコア23251

takyafumin, len_souko, GiveAHand, sheephuman, exclaire👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

GiveAHand

2016/06/18 14:06

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

3

こんにちは。

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

投稿2016/06/18 13:47

Tak1wa

総合スコア4784

len_souko, GiveAHand, exclaire👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

GiveAHand

2016/06/18 14:04

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

2

上記プログラムですと、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

len_souko, GiveAHand👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

GiveAHand

2016/06/18 14:03

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

2016/06/18 14:07

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

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C#

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