- PR -

C# ArrayList のコピーについて

投稿者投稿内容
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-09-08 18:17
catsさん、囚人さんありがとうございます。
返信が遅くなってしまい、申し訳ありません。
ディープコピーは結局よく分からず、感覚でいくと

ArrayList list2 = new ArrayList();
for(int i = 0 ; i < _list.Count ; i++)
{
clsData d = (clsData)_list[i];
clsData a = new clsData();
a.No = d.No;
a.Data = d.Data;
list2.Add(a);
}

このように、書かなくては、いけないということなのでしょうか。
(勉強不足で申し訳ありません)

囚人さんの、MemberwiseClone() <これまた新しい言葉です・・・>
はバッチリできました。

と思ったのですが、やはり「10」と出てしまいました。
MemberwiseCloneでもできないとなると、上記のように、記述しなくては
いけないということなのでしょう・・・・・

本当に皆様ありがとうございました。
とても、勉強になりました。



[ メッセージ編集済み 編集者: もも 編集日時 2005-09-08 18:24 ]
葉瀬崎浩樹
大ベテラン
会議室デビュー日: 2005/06/28
投稿数: 115
お住まい・勤務地: 兵庫県
投稿日時: 2005-09-08 18:42
引用:

ももさんの書き込み (2005-09-08 18:17) より:
ディープコピーは結局よく分からず、感覚でいくと

ArrayList list2 = new ArrayList();
for(int i = 0 ; i < _list.Count ; i++)
{
clsData d = (clsData)_list[i];
clsData a = new clsData();
a.No = d.No;
a.Data = d.Data;
list2.Add(a);
}

このように、書かなくては、いけないということなのでしょうか。


感覚的にはそれでつかめてると思います。
勿論そこまでべた書きすると、
生産・保守性ともに低下するので
コピー処理のコードは、メソッドに引越しするべきです。

コード:

// そっくりさんを作る。べた書きVer
clsData MakeDeepCopy( clsData copyFrom )
{
//メンバを全部コピーする
clsData copyTo = new clsData();
copyTo.No = copyFrom.No;
copyTo.Data = copyFrom.Data;
return copyTo;
}

// そっくりさんを作る。OOPっぽいVer
clsData GetClone()
{
//メンバを全部コピーする
clsData copy = new clsData();
copy.No = this.No;
copy.Data = this.Data;
return copy;
}


こんな感じのコードでしょうかね。

引用:

MemberwiseCloneでもできないとなると、上記のように、記述しなくては
いけないということなのでしょう・・・・・



MemberwiseCloneはシャローコピー(簡易コピー・浅いコピー)です。
って、リンク先に書いてあったような。。

で、MemberwiseCloneっていうのは(推測ですけど)
IClonableインタフェイスを継承して、Clone()を独自実装してしまうと、
Clone()でシャローコピーができなくなりますよね。
で、その回避用メソッドとして MemberwiseClone()が提供されていて、
こちらは、常にシャローコピーを返してくれるのだと思います。

#1敲が大嘘のコードだったので修正
#さらに修正orz

[ メッセージ編集済み 編集者: 葉瀬崎浩樹 編集日時 2005-09-08 18:56 ]
未記入
会議室デビュー日: 2003/09/24
投稿数: 18
投稿日時: 2005-09-08 19:10
clsDataクラスにclsData自身が引数のコンストラクタを作る方法です。
コード:
//その他全て省略
Class clsData
{
 //コピーするコンストラクタ
  public clsData (clsData cl)
  {
    //メンバを全部コピーする
    this.No = cl.No
    this.Data = cl.Data
  }
}



コピーをListに加える
コード:
  ArrayList list2 = new ArrayList(); 
  for(int i = 0 ; i < _list.Count ; i++) 
  { 
   list2.Add(new clsData((clsData)_list[i])); 
  } 


こんな感じでどうですか?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-09-08 19:47
> IClonableも使うときに、キャストがいるので嬉しくないです。
 明示実装して隠蔽してます。こんな感じ。
コード:
class clsData : IClonable {
    private int _no;
    private string _strValue;
...適当に省略...
    object IClonable.Clone() {
        // 明示実装して隠す
        return this.Clone();
    }
    public clsData Clone() {
        clsData ret = new clsData();
        ret._no = this._no;
        ret._strValue = this._no;
        return ret;
    }
}


インターフェイスにキャストして呼ばれると、キャストし直さなければなりませんが...


> clsDataクラスにclsData自身が引数のコンストラクタを作る方法です
 あ〜!!なんか、「コピーコンストラクタは作れない」と思いこんでいた。。。
何でだったんだろう??
_________________
もも
常連さん
会議室デビュー日: 2005/07/25
投稿数: 46
投稿日時: 2005-09-08 19:54
葉瀬崎浩樹さま、未記入さま、Jittaさま本当にありがとうございます。

MemberwiseCloneについて、ご教授いただきありがとうございます。
調べ足りない自分を反省します。

> clsDataクラスにclsData自身が引数のコンストラクタを作る方法です
未記入さまさまの方法には、ビックリしました。
コンストラクタにこんな使い方があるのですね。

C# 奥が深いです・・・・・

囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-09-08 19:56
class clsData : ICloneable
{
public int No;
public string Data;

object Clone()
{
return MemberwiseClone();
}
}

こういうときに、MemberwiseClone() を使うのでは?


[ メッセージ編集済み 編集者: 囚人 編集日時 2005-09-08 19:57 ]
葉瀬崎浩樹
大ベテラン
会議室デビュー日: 2005/06/28
投稿数: 115
お住まい・勤務地: 兵庫県
投稿日時: 2005-09-08 20:17
引用:

囚人さんの書き込み (2005-09-08 19:56) より:
こういうときに、MemberwiseClone() を使うのでは?



あー、protectedメンバやったんや。。
そのように使うのが正しいですね。
大変勉強になります!

#というか、自分こそちゃんとドキュメントしっかり読めと

[ メッセージ編集済み 編集者: 葉瀬崎浩樹 編集日時 2005-09-08 20:19 ]
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-09-08 20:28
引用:

あー、protectedメンバやったんや。。
そのように使うのが正しいですね。
大変勉強になります!

#というか、自分こそちゃんとドキュメントしっかり読めと



いやぁ、結局簡易コピーは簡易コピーなんですよね。
自分のオブジェクトグラフに対して全て MemberwiseClone() を呼んでくれるようなものがあれば、幸せだなぁと思うときがたまにあるんですよね。駄目な理由って何かあるんでしょうか。

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