C#:同じクラスのインスタンスでプロパティの値をコピーする
C#には暗黙的なコピーコンストラクタは作られない。
なので、いちいちメンバ変数をコピーするような定義をしないといけないわけだが。
まあ、面倒なほどメンバ変数を一つのクラスに定義するのは設計的に下策なのかもしれないけれど、テストで作成するにはそんなことしたくない。
というわけで、限定的になるけれど、getterとsetterのプロパティがある場合、それらを利用してインスタンスの持つ値をコピーする方法を考えてみた。
public class classParameter
{
public classParameter()
{
}
public classParameter(classParameter param)
{
this.clone(param);
}
public void clone(classParameter param)
{
Type t = typeof(classParameter);
PropertyInfo[] members = t.GetProperties();
/*
for (int i = 0; members.Length > i; i++)
{
if (members[i].CanWrite)
{
t.InvokeMember(members[i].Name, BindingFlags.SetProperty, null, this, new object[] { t.InvokeMember(members[i].Name, BindingFlags.GetProperty, null, param, null) });
}
}
*/
foreach (PropertyInfo p in members)
{
if (p.CanWrite && p.CanRead)
{
t.InvokeMember(p.Name, BindingFlags.SetProperty, null, this, new object[] { t.InvokeMember(p.Name, BindingFlags.GetProperty, null, param, null) });
}
}
}
public string parameterFileName
{
get { return "sachimitama.ini"; }
}
public string version
{
get { return "00-00-000"; }
}
// 処理方式
// ファイルの読み込み方法
private int readMode_;
public int readMode
{
get { return readMode_; }
set { readMode_ = value; }
}
// ファイルの書き込み方法
private int writeMode_;
public int writeMode
{
get { return writeMode_; }
set { writeMode_ = value; }
}
}
例によって適当に作ったものの一部抜粋したものなのだが・・・。
クラスの持つプロパティやメソッドの情報をtypeof()で取得できる。そこからプロパティ情報の一覧がGetProperties()で取得できる。
そして、InvokeMember()を使うことにより、プロパティの名称からgetterプロパティの値を取得したり、setterプロパティに値を設定することができる。
組み合わせれば、コピー元のgetterプロパティから取得した値を、コピー先のsetterプロパティに値を設定することができる。
プロパティにはgetterだけのものがあるので、それの判定をCanWriteプロパティ(bool値)で行う。上記のプログラムでは、for文を使っているけれど、foreach文でもいいかもしれない。その時はMemberInfoではなくPropertyInfoに入れるようにすれば、CanWriteプロパティがつかえるのか?参考にしたサイトではMemberInfoに入れていて、MemberInfoではCanWriteプロパティがないので、こんな風にしてしまったのだが。
後で調べてみよう・・・。
今日、お仕事の方でバグが出て帰るのが遅くなったんで、ここまでとします。
→2008/10/4 修正:for文をforeachに変えて、PropertyInfoに入れてみました。ついでにプロパティの判定にgetterとsetterがあることを判定しています。setterだけのプロパティのとき例外が発生しちゃうもんね。
« 情報処理技術者試験受験票が来てしまった・・・ | トップページ | 今日買ってきたもの »
コメント