- PR -

C# ArrayListに追加した構造体の内容の変更

1
投稿者投稿内容
くらす
会議室デビュー日: 2005/10/04
投稿数: 6
投稿日時: 2005-10-04 01:42
はじめまして。宜しくお願いします。
現在C#で開発を行っています。
ArrayListに追加した構造体の値を変更したいのですが、
方法が分かりません。ご教授お願い致します。

struct STR{
int a;
public void set_a(int value){ a = value; }
}
ArrayList arr = new ArrayList();
STR str;
str.a = 0;
arr.Add (str);
としたときに
((STR)arr[0]).a には0が入っていると思いますが、
((STR)arr[0]).aの値を変更するにはどうすればいいのでしょうか。
arr.Add (str) とした時に、ボックス化変換するためstrのコピーが作成されて、
そのコピーの参照がarrに追加されたと思っております。
そのために、
((STR)arr[0]).set_a(1);
とした時、str.aの値は変更されないとは思いますが、
((STR)arr[0]).aの値は1になると思っていましたが0のままです。
どうしてなのでしょうか。
また、((STR)arr[0]).a の値を変更することは可能なのでしょうか。

ご助言宜しくお願いいたします。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2005-10-04 02:02
キャストでまとめて書こうとするから分かりにくくなります。
分割して書いてみましょう。
コード:
((STR)arr[0]).set_a(1);


これは
コード:
STR str0 = (STR)arr[0];
str0.set_a(1);


と同じです。
この一行目でコピーが発生するのは明らかでしょう。
STRは構造体ですから、参照のコピーではなく値のコピーと言うことになります。
つまりarr[0]とstr0は各フィールドの値が等しいだけの別物と言うことです。
別物ですから、str0を幾ら操作したところでarr[0]のオブジェクトにはなんの影響も出ません。

str0の何らかの状態を変更しました。
コード:
str0.set_a(123);


さてではarr[0]にどうやって戻しましょう?
さっきやったことの反対をやればいいのです。
つまり、arr[0]にstr0をコピーしてやるということ。
コード:
arr[0] = str0;



ところで、折角C#にはプロパティというものがあるのですから、STR構造体のaを変更するのにもプロパティを利用したらどうでしょうか。

余談:
個人的には、この構造体のコピーに関する問題から、構造体が自身のメソッドで状態を変化させるというのは良くないと考えます。
構造体のメソッドは自分の状態を変えるのではなく、状態が変化した新しい構造体を作成すると言う方がバグが出にくくなります。
状態をプロパティでのみ操作するようにすれば、コピーが発生して元のインスタンスに影響が与えられない状況でプロパティを操作したときに、コンパイラがエラーを出してくれますから。
くらす
会議室デビュー日: 2005/10/04
投稿数: 6
投稿日時: 2005-10-04 02:53
早速の返答どうもありがとうございます。

引用:
これは
コード:
STR str0 = (STR)arr[0];
str0.set_a(1);
と同じです。
この一行目でコピーが発生するのは明らかでしょう。
STRは構造体ですから、参照のコピーではなく値のコピーと言うことになります。


キャストする時にもコピーされるんでしたね。うっかりしていました。

引用:

状態をプロパティでのみ操作するようにすれば、コピーが発生して元のインスタンスに影響が与えられない状況でプロパティを操作したときに、コンパイラがエラーを出してくれますから。

 

そういったこともプロパティの利点ですね。初めて知りました。
勉強不足でした。確かに構造体の内容を
コード:
struct STR{ 
  int a; 
  public void set_a(int value){ a = value; } 
  public int A 
  {
     set{a = value;}
  }
}


とプロパティを追加して、アレイリストからキャストしてプロパティを
操作するとコンパイルエラーとなりました。勉強になります。

丁寧な回答と補足まで付けて頂きありがとうございます。
おかげで理解することができました。




囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-10-04 08:47
こんにちは。

余計な事かも知れませんが・・・。
set しかできないプロパティは 混乱するのでは?


[ メッセージ編集済み 編集者: 囚人 編集日時 2005-10-04 08:48 ]
くらす
会議室デビュー日: 2005/10/04
投稿数: 6
投稿日時: 2005-10-04 15:08
引用:

set しかできないプロパティは 混乱するのでは?


ご指摘ありがとうございます。
ただ単にgetを記述していなかっただけでした。実際はgetも使用しています。
これからは誤解のないよう記述するよう気をつけます。
1

スキルアップ/キャリアアップ(JOB@IT)