クラスを CSV にデバインドする カラム名自由編 (C#)
クラスを CSV にデバインドする (C#)は有用だが、CSV のヘッダには日本語やカッコなどの識別子に使えないカラム名を使いたいということがあるのでそれに対応する.
[AttributeUsage(AttributeTargets.Property)]publicclassHeaderNameAttribute:Attribute{publicstringName{get;privateset;}publicHeaderNameAttribute(stringname){Name=name;}}publicclassContract{publicintRowId{get;set;}[HeaderName("契約ID")]publicstringId{get;set;}[HeaderName("開始日")]publicDateTimeStartDate{get;set;}[HeaderName("終了日")]publicDateTime?StopDate{get;set;}[HeaderName("顧客ID")]publicintCustomerId{get;set;}}
みたいなクラスがあって
RowId,契約ID,開始日,終了日,顧客ID
0,C0001,2020-03-01T00:00:00.0000000,2020-04-01T00:00:00.0000000,0
1,C0002,2020-03-01T00:00:00.0000000,,1
みたいな、CSV にデバインドしたいという話です. CSV 変換は今回は話題にしたくないので、string.Join(",", v)
で片付くということにしましょう.
Save を以下のコードに置き換えると、Save(stream, contracts);
でデバインドできます.
publicstaticvoidSave<T>(Streamstream,IEnumerable<T>content,Encodingencoding=null)whereT:class{if(encoding==null)encoding=Encoding.UTF8;using(varwriter=newStreamWriter(stream,encoding)){varheaderName=typeof(T).GetProperties().Select(e=>{vara=Attribute.GetCustomAttributes(e,typeof(HeaderNameAttribute));if(a.Length==0){returne.Name;}else{return(a[0]asHeaderNameAttribute).Name;}}).ToList();writer.WriteLine(string.Join(",",headerName));varheader=typeof(T).GetProperties().Select(e=>e.Name).ToList();varheaderMap=newDictionary<string,int>();for(vari=0;i<header.Count;i++){headerMap[header[i]]=i;}foreach(varoincontent){writer.WriteLine(string.Join(",",Debind(headerMap,o)));}}}