基於以上構想,我需要一個能將任意匿名型別陣列或List自動轉成CSV的共用函數,挑戰點在於陣列元素型別未知,但這可難不倒C#,祭出Reflection就能輕鬆克服。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace AnonymousTypeListReflectionTest
{
class Program
{
static void Main(string[] args)
{
var ary = "Jeffrey,Darkthread,Geek".Split(',')
.Select(o => new
{
文字 = o,
長度 = o.Length
}).ToArray();
Console.Write(convToCsv(ary));
Console.Read();
}
//將任意型別陣列輸出為CSV,第一列為標題列舉欄位名稱
static string convToCsv(Array ary)
{
//取得陣列元素的型別
Type elemType = ary.GetType().GetElementType();
PropertyInfo[] props = elemType.GetProperties();
StringBuilder sb = new StringBuilder();
//第一列輸出屬性名稱
sb.AppendLine(string.Join("\t", props.Select(o => o.Name).ToArray()));
//藉由foreach巡迴每一元件,透過Refelction取出屬性值
foreach (object elem in ary)
{
sb.AppendLine(string.Join("\t",
props.Select(o => Convert.ToString(o.GetValue(elem, null)))));
}
return sb.ToString();
}
}
}
實際寫完,程式遠比預期來得單純: 傳入參數時,將匿名型別陣列轉型成Array、GetElementType()可以找出陣列元素型別、Reflection GetProperties()跟PropertyInfo.GetValue()已是老把戲不用多說,至於分隔符號我選擇用Tab "\t"取代逗號,以省去處理屬性值內含逗號的麻煩。