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

CSV をクラスにバインドする カラム名自由編 (C#)

$
0
0

CSV をクラスにバインドする カラム名自由編 (C#)

CSV をクラスにバインドする (C#)は有用だが、CSV のヘッダには日本語やカッコなどの識別子に使えないカラム名を使いたいということがあるのでそれに対応する.

例えば

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 があるとする.

カラム名を指定するための HeaderName 属性を用意します.

[AttributeUsage(AttributeTargets.Property)]publicclassHeaderNameAttribute:Attribute{publicstringName{get;privateset;}publicHeaderNameAttribute(stringname){Name=name;}}

そしてバインド対象のクラスのプロパティーにHeaderName 属性を使ってカラム名をアノテーションします.

publicclassContract{publicintRowId{get;set;}[HeaderName("契約ID")]publicstringId{get;set;}[HeaderName("開始日")]publicDateTimeStartDate{get;set;}[HeaderName("終了日")]publicDateTime?StopDate{get;set;}[HeaderName("顧客ID")]publicintCustomerId{get;set;}}

後は Load を以下に変更すると、var contracts = Load<Contract>(fstream).ToArray();でバインドできます.

publicstaticIEnumerable<T>Load<T>(Streamstream,Encodingencoding=null)whereT:class,new(){if(encoding==null)encoding=Encoding.UTF8;using(varreader=newStreamReader(stream,encoding)){varheader=reader.ReadLine().Split(",");varheaderNameMap=typeof(T).GetProperties().Select(e=>{vara=Attribute.GetCustomAttributes(e,typeof(HeaderNameAttribute));if(a.Length==0){returnnewKeyValuePair<string,string>(e.Name,e.Name);}else{returnnewKeyValuePair<string,string>((a[0]asHeaderNameAttribute).Name,e.Name);}}).ToDictionary(e=>e.Key,e=>e.Value);varheaderMap=newDictionary<string,int>();for(vari=0;i<header.Length;i++){headerMap[headerNameMap[header[i]]]=i;}while(true){varline=reader.ReadLine();if(line==null)break;yieldreturnBind<T>(headerMap,line.Split(","));}}}

関連記事: クラスを CSV にデバインドする カラム名自由編 (C#)


Viewing all articles
Browse latest Browse all 9525

Trending Articles