かきスタンプ

福岡でフリーランスの物流系のエンジニアやってます。

C#:DBから取得したModelのリストを、Modelを継承した要素で表現する

こういう状況。

  • Model定義されたクラスがある
  • Model のデータは、DBなどから参照し、List にしている
  • List の中身を、Model を拡張したクラスで表現したい(画面制御のみで使用するプロパティを付与したい)
(例)
List<Users>        //Model(のリスト)
List<ExtendUsers>  //Modelを拡張したクラス(のリスト)

こういうのがあって、List<ExtendUsers> に、List<Users> の要素をブチ込みたい、といったケース。

ストレートにダウンキャストが使えないんで、以下のような工夫をしてみた。
 
分割しているのは、全部繋げるとスクロールバーが一番下にしか来なくて、読みづらかったためです。

//親クラス
class Users
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Position { get; set; }
}
//子クラス
class ExtendUsers : Users
{
    public bool IsChecked { get; set; } //画面の制御用として、子だけで使いたいプロパティ

    public ExtendUsers(Users value) //コンストラクタの引数に、親のインスタンスを渡す
    {
        //---------------------
        //  親要素の全プロパティをリストアップし、子に同じ値を設定
        //---------------------
        PropertyInfo[] propertyInfoinfoArray = value.GetType().GetProperties();  //プロパティをリストアップ
        foreach (PropertyInfo item in propertyInfoinfoArray) //リストアップしたプロパティをループで回す
        {
            var property = value.GetType().GetProperty(item.Name);  //プロパティを取得
            property.SetValue(this, item.GetValue(value));          //子に親と同じ値をセット
        }
    }
}
//Model定義されたクラスのリスト(ここに書いてると、そう見えないけど、そういう事にしといて下さい。)
private List<Users> _users;
//Model定義されたクラスを拡張した要素を詰め込んだリスト
private List<ExtendUsers> _extendUsers;

private void MyButton01_Click()
{
    _extendUsers = new List<ExtendUsers>();
    foreach (var item in _users) //Model定義された要素が入ったリストをループ回す
    {
        ExtendUsers el = new ExtendUsers(item); //子のインスタンス作成時、親のインスタンスを引数に渡す。(詳細は上記を参照)
        _extendUsers.Add(el); //親のインスタンスと同じ値を設定した子を、リストに追加
    }
}
//============================
// サンプルソースを動かすために用意した。本当はDBから引っ張ってくる
//============================
private void SetUsersList()
{
    _users = new List<Users>();
    _users.Add(new Users { Id = 1, Name = "Tanaka", Position = 1 });
    _users.Add(new Users { Id = 2, Name = "Yamada", Position = 1 });
    _users.Add(new Users { Id = 3, Name = "Watanabe", Position = 2 });
}
概要
  • 親要素が入ったリストをループで回している
  • 子のインスタンスを作成する時、コンストラクタに親のインスタンスを渡している
  • コンストラクタにて、親のプロパティの一覧を精査し、同じ値を子に設定している

 
 
もっといい方法がありそうだけど、今の自分にはこの辺が限界。