/// <summary> /// オブジェクトから文字列としてのCSVデータを取得します /// </summary> /// <typeparam name="T"> Entityの型 </typeparam> /// <param name="contents"> T型オブジェクトのList </param> /// <returns> CSVデータ(Iterator) </returns> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentOutOfRangeException"></exception> /// <exception cref="NotSupportedException"></exception> /// <exception cref="TypeLoadException"></exception> /// <exception cref="AmbiguousMatchException"></exception> /// <exception cref="RegexMatchTimeoutException"></exception> public IEnumerable <string> GetCsvString <T>(List <T> contents) where T : new() { PropertyInfo[] properties = typeof(T).GetProperties(); string[] propNames = properties.Select((x) => x.Name).ToArray(); // T型オブジェクトの情報をstringのListに変換するローカル関数 List <string> getValues(T obj) { var l = new List <string>(propNames.Length); foreach (string n in propNames) { l.Add(typeof(T).GetRuntimeProperty(n).GetValue(obj).ToString()); } return(l); }; // ヘッダーを出力する場合 if (HasHeader) { string header = string.Empty; foreach (var prop in properties) { // Propertyに紐付いた属性値を取得 HeaderAttribute header_atrb = prop.GetCustomAttribute <HeaderAttribute>(); if (header_atrb != null && (!string.IsNullOrWhiteSpace(header_atrb.Name))) { // 属性値が設定されていて、属性値が空文字・空白でない場合 // ヘッダーとする header += header_atrb.Name + Delimiter.ToString(); } else { header += prop.Name + Delimiter.ToString(); } } yield return(header.Remove(header.Length - 1, 1)); } // T型オブジェクトから行ごとのデータを返す foreach (var ctn in contents) { yield return(GetLineData(getValues(ctn))); } }
/// <summary> /// 読み込まれたCSVデータの内容をカスタムオブジェクトで取得します /// </summary> /// <typeparam name="T"> マッピングするオブジェクトの型 </typeparam> /// <returns> マッピングされたオブジェクトのList </returns> /// <exception cref="ArgumentException"></exception> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="NotSupportedException"></exception> /// <exception cref="MissingMethodException"></exception> /// <exception cref="MethodAccessException"></exception> /// <exception cref="InvalidCastException"></exception> /// <exception cref="OverflowException"></exception> /// <exception cref="FormatException"></exception> /// <exception cref="TypeLoadException"></exception> /// <exception cref="TargetException"></exception> /// <exception cref="TargetInvocationException"></exception> /// <exception cref="AmbiguousMatchException"></exception> /// <exception cref="FailedMappingException"></exception> public List <T> GetContents <T>() where T : new() { var res = new List <T>(); var maps = new List <MappingObject>(); if (Headers.Count == 0) { return(res); } PropertyInfo[] properties = typeof(T).GetProperties(); if (properties.Length != Headers.Count) { throw new FailedMappingException ("マッピングしようとしているPropertyの数とヘッダーの数が一致しません。"); } foreach (PropertyInfo prop in properties) { var map = new MappingObject(); // Propertyに紐付いた属性値を取得 HeaderAttribute header_atrb = prop.GetCustomAttribute <HeaderAttribute>(); if (prop.PropertyType.Name.Contains("Nullable")) { // Nullableの型の時 // GetUnderlyingTypeから型を取得する map.ObjectType = Nullable.GetUnderlyingType(prop.PropertyType); // Nullableフラグを立てる map.IsNullable = true; } else { // Nullableの型でないときは普通にPropertyTypeから取得 map.ObjectType = prop.PropertyType; } if (header_atrb != null && Headers.Contains(header_atrb.Name)) { // 属性値が設定されていて、属性値に対応するヘッダーが存在している場合 // ヘッダーに対応するプロパティ名を取得 map.Name = prop.Name; map.Number = Headers.IndexOf(header_atrb.Name); } else if (Headers.Contains(prop.Name)) { // 属性値が設定されていなければヘッダーに対応するプロパティ名を // 検索して取得 map.Name = prop.Name; map.Number = Headers.IndexOf(prop.Name); } else { throw new FailedMappingException ("ヘッダー名称がマッピングしようとしているオブジェクト内に" + "存在しません。"); } maps.Add(map); } // プロパティに値を設定するためのローカル関数 void setValue(ref T obj, string propName, object value) => typeof(T).GetRuntimeProperty(propName).SetValue(obj, value); foreach (var ctn in Contents) { // ジェネリクスのインスタンス作成 var Tobj = Activator.CreateInstance <T>(); foreach (var map in maps) { // コンテンツから値を取得 string str = ctn[map.Number]; if (map.ObjectType.Equals(typeof(string))) { // マッピング先の型がstringならそのまま値を入れる setValue(ref Tobj, map.Name, str); } else { // マッピング先の型がstring以外なら値を変換 TypeCode code = Type.GetTypeCode(map.ObjectType); object value = string.IsNullOrWhiteSpace(str) ? null : str.ConvertValue(code); // valueがnullで、マッピング先の型がNullableでない場合を除き // 値を設定する if (!(value == null && (!map.IsNullable))) { setValue(ref Tobj, map.Name, value); } // valueがnullで、マッピング先の型がNullableでない場合は // マッピング先クラスのコンストラクタの初期値に依存させる } } res.Add(Tobj); } return(res); }