- - PR -
自作クラスのコレクションの扱い(CopyToメソッドを実装するべき?)
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 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 | ||||||||
|
投稿日時: 2004-02-10 15:23
コレクションに100個のエントリがあるなら、
その実体も100個必要です。 (共有していいものがなければ) なので、1つ1つnewするのは仕方ないです。 List()がCompanyインスタンスのメソッドのようですが、 (ソースではクラス外にあるので違うかも) これが不自然だから根本的におかしくな感じになっているのではないでしょうか。 せめて、List()をstaticメソッドにするか、他のクラスにこの仕事をやらせましょう。 どちらの方法をとっても this.m_CdCompnayやthis.m_NmCompnayは使えません。 よって、やはり1つずつnewすることになります。 p.s.
↑最初のCompanyCollectionは使用されずに参照が失われているので意味が ないですよ。。 [ メッセージ編集済み 編集者: ナキヲ 編集日時 2004-02-10 15:26 ] | ||||||||
|
投稿日時: 2004-02-10 20:30
ごてんです。
ナキヲさん、ご回答ありがとうございました。 List()はコレクション側でやらせてみようと思います。 意味のない「new」が他にもないかコードを見直してみます。 つたないコードを読んでいただき、ありがとうございました。 |
1