Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9725

[C#] クラスのメンバ(プロパティ)をインデクサを使って、リストのように扱う

$
0
0

データ型クラスのプロパティメンバを、リストのようにインデクサでアクセス出来るようにしたい。

題材

下記のUserInfoクラスのプロパティを、インデクサでアクセス出来るようにする。

classProgram{staticvoidMain(string[]args){varUser=newUserInfo(newList<string>{"012","user","pass","xx@xx.com"});}publicclassUserInfo{publicUserInfo(List<String>userList){ID=userList[0];Name=userList[1];Password=userList[2];email=userList[3];}publicstringID{get;set;}publicstringName{get;set;}publicstringPassword{get;set;}publicstringemail{get;set;}}}

前準備 添字でアクセス

classProgram{staticvoidMain(string[]args){varUser=newUserInfo(newList<string>{"012","user","pass","xx@xx.com"});//添字でアクセスUser["ID"]="dummy";if(User.ID=="dummy"){//成功}}publicclassUserInfo{publicUserInfo(List<String>userList){varproperties=typeof(UserInfo).GetProperties();{for(vari=0;i<userList.Count;i++){varname=properties[i].Name;//userListでプロパティをまとめて初期化this[name]=userList[i];}}}publicstringID{get;set;}publicstringName{get;set;}publicstringPassword{get;set;}publicstringemail{get;set;}privatestringthis[stringpropertyName]{get=>typeof(UserInfo).GetProperty(propertyName).GetValue(this).ToString();set=>typeof(UserInfo).GetProperty(propertyName).SetValue(this,value);}}}

解説

string this[string propertyName]

このプロパティを追加することで、添字によるアクセスが可能になる。

get
  • typeof(クラス名).GetProperty(propertyName).GetValue(this)

↑GetValueの戻り値はobject型なので、string型に変換している。

set
  • typeof(クラス名).GetProperty(propertyName).SetValue(this,value)

コンストラクタ

  • typeof(UserInfo).GetProperties()クラスのプロパティを配列で取得。
  • properties[i].Name各プロパティ名を取得出来るので、ループ処理が可能になる。

このままだとあまり意味が無いので、インデクサでアクセス出来るようにする。

本番 インデクサでアクセス

下記をUserInfoクラスに追加

privateList<string>NameList;publicstringthis[intnum]{get=>this[NameList[num]];set=>this[NameList[num]]=value;}

NameListはプロパティ名一覧が入ったリストとして使います。

string this[int num]

this[string propertyName]をラッパー。
NameList[num]でthis[string propertyName]の添字に変換します。
これにより、インデクサでのアクセスが出来るようになります。

全体像

classProgram{staticvoidMain(string[]args){varUser=newUserInfo(newList<string>{"012","user","pass","xx@xx.com"});//添字でアクセスUser["ID"]="dummy";if(User.ID=="dummy"){//成功}Console.WriteLine(User[2]);//passforeach(varname){Console.WriteLine(User.ToList());//012,user,pass,xx@xx.comの順に表示される}}publicclassUserInfo{publicUserInfo(List<String>userList){varproperties=typeof(UserInfo).GetProperties();NameList=newList<string>();//propertiesから、各Name取り出しforeach(var(name,index)inproperties.Select((prop,index)=>(prop.Name,index))){if(index==properties.length-1){//配列の最後はthisプロパティなので、スキップするbreak;}//UserInfoのプロパティ名のリストを作成NameList.Add(name);//全プロパティを初期化this[name]=headerlist[index];}}publicstringID{get;set;}publicstringName{get;set;}publicstringPassword{get;set;}publicstringemail{get;set;}privateList<string>NameList;privatestringthis[stringpropertyName]{get=>typeof(UserInfo).GetProperty(propertyName).GetValue(this).ToString();set=>typeof(UserInfo).GetProperty(propertyName).SetValue(this,value);}publicstringthis[intnum]{get=>this[NameList[num]];set=>this[NameList[num]]=value;}publicList<string>ToList(){varres=newList<string>();NameList.ForEach(name=>res.Add(this[name]));returnres;}}}

補足

  • public List<string> ToList()

thisではリストを返さないため、別途リスト取得用のメソッドを設けています。

参考

【C#】プロパティ名でプロパティにアクセスする


Viewing all articles
Browse latest Browse all 9725

Trending Articles