- PR -

自作クラスのコレクションの扱い(CopyToメソッドを実装するべき?)

1
投稿者投稿内容
GO-TEN
常連さん
会議室デビュー日: 2003/12/07
投稿数: 20
投稿日時: 2004-02-10 14:22
C#初心者のごてん(仮名)と申します。
VB6.0での開発経験/Javaでの設計経験はありますが、C#は開発・設計とも初めてです。

やりたいのは、自作クラスの"中身"(参照ではなく)をコレクションに追加したいのです。
自作クラスにCopyやCopyToなどといったメソッドを実装するべきなのかもしれませんが、どのように実装してよいのかわかりません。
やむなく下記(2)のようにデータベースを読むループの中で、自作クラスを次々とNewしているのですが、いつ解放されるか?メモリ不足にならないかと不安です。
本当はコード(1)のようにひとつのインスタンスを使いまわして、それをコレクションに追加したいのですが、データベースの値を読むループの中でNewしないと、結果(1)のようにコレクションに追加した値が全て書き換わってしまいます(参照型なので当然でしょうが)。
通常自作クラスをコレクションで扱う場合、どのようにするのがベストなのでしょうか?
ご教授いただけるとありがたいです。

コード抜粋:
// 呼び出し元
 private void Test()
{
  private CompanyCollection Col = new CompanyCollection();
  private Company c = new Company();
  Col = c.List();
  for (int i=0; i<Col.Count; i++)
  {
   Console.WriteLine(Col.Item(i).ViewCdCompany);
   Console.WriteLine(Col.Item(i).ViewNmCompany);
  }
 }

 //自作クラス
 public class Company
 {
  private string m_CdCompany = "";
  private string m_NmCompany = "";
  private bool m_Error = false;
  //中略//
  public string ViewCdCompany
  {
   get {return m_CdCompany;}
  }
  public string ViewNmCompan
  {
   get {return m_NmCompany;}
  }
 }
 //コレクションを返すメソッド
 public MstCompanyCollection List()
 {
  SqlCommand cmd = new SqlCommand();
  SqlConnection con = new SqlConnection();
  CompanyCollection col = new MstCompanyCollection();
  try
  {
   cmd.CommandText = "SELECT CD_COMPANY,NM_COMPANY FROM COMPANY_TABLE";
   con.ConnectionString =System.Configuration.ConfigurationSettings.AppSettings["ConnectionString"];
   cmd.Connection = con;
   con.Open();
   SqlDataReader rdr = cmd.ExecuteReader();
   while (rdr.Read())
   {
    // (1)実際にしたいコード
    // this.m_CdCompnay = rdr.GetString(1);
    // this.m_NmCompnay = rdr.GetString(2);
    // col.Add(this);
    // (2)ループ内でNew
    Company c = new Company();
    c.m_CdCompany.Value = rdr.GetString(1);
    c.m_CdCompany.Value = rdr.GetString(2);
    col.Add(c);
   }
   rdr.Close();
   return col;
  }catch (System.Exception err){throw new Exception(err.Message,err);}
  finally
  {
   cmd.Dispose();
   con.Dispose();
  }
 }

 // 自作コレクション
 public class CompanyCollection : System.Collections.CollectionBase
 {
  public void Add(MstCompany mc)
  {
   List.Add(mc);
  }
 }

結果:
(1)ひとつのインスタンス
 C00002
 会社C
 C00002
 会社C
 C00002
 会社C

(2)ループ内側でNew
 C00000
 会社A
 C00001
 会社B
 C00002
 会社C
ナキヲ
常連さん
会議室デビュー日: 2003/08/22
投稿数: 32
お住まい・勤務地: 京都・自宅から勤務地まで自転車で40分
投稿日時: 2004-02-10 15:23
コレクションに100個のエントリがあるなら、
その実体も100個必要です。
(共有していいものがなければ)

なので、1つ1つnewするのは仕方ないです。
List()がCompanyインスタンスのメソッドのようですが、
(ソースではクラス外にあるので違うかも)
これが不自然だから根本的におかしくな感じになっているのではないでしょうか。

せめて、List()をstaticメソッドにするか、他のクラスにこの仕事をやらせましょう。
どちらの方法をとっても
this.m_CdCompnayやthis.m_NmCompnayは使えません。
よって、やはり1つずつnewすることになります。

p.s.
引用:

コード:

  private CompanyCollection Col = new CompanyCollection();
  private Company c = new Company();
  Col = c.List();




↑最初のCompanyCollectionは使用されずに参照が失われているので意味が
ないですよ。。


[ メッセージ編集済み 編集者: ナキヲ 編集日時 2004-02-10 15:26 ]
GO-TEN
常連さん
会議室デビュー日: 2003/12/07
投稿数: 20
投稿日時: 2004-02-10 20:30
ごてんです。

ナキヲさん、ご回答ありがとうございました。
List()はコレクション側でやらせてみようと思います。
意味のない「new」が他にもないかコードを見直してみます。
つたないコードを読んでいただき、ありがとうございました。
1

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