一直以來C#委派的語法總是很難搞懂,有一天寫一寫javascript的callback,突然感覺好像就是一樣的東西,似乎也沒那麼難,剛好有時間就找找範例來練習一下
從 CSV 文字檔中讀取紀錄,然後轉成 dto 進行其他操作
- 方法 A:從檔案中取得資料,逐行執行某些行為
- 方法 B:將文字轉換為 DTO 實體
為了不要讓某些事情的程式碼寫死在方法 A 裡面,具體的行為應從外部傳入給方法 A,所以透過委派的方式來做
private static void Main(string[] args)
{
// 先宣告一個委派,輸入為字串,輸出是自訂的DTO物件,具體的方法則是定義在ConvertStrToDto
Func<string, OutBoundUserCsv> myHandler = ConvertStrToDto;
ReadCsvFile(myHandler);
Console.ReadKey();
}
private static OutBoundUserCsv ConvertStrToDto(string source)
{
// 將原始字串切割為陣列後逐一填入entity
var d = source.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
return new OutBoundUserCsv()
{
UserId = d[0],
UserName = d[1]
};
}
private static void ReadCsvFile(Func<string, OutBoundUserCsv> myHandler)
{
// 透過StreamReader讀取檔案,否則檔案很大的話會拖垮系統
using (var reader = new StreamReader("Input.txt"))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var usr = myHandler.Invoke(line);
Console.WriteLine($"UserId:[{usr.UserId}] Name:[{usr.UserName}] ");
}
}
}
當然不要重複造輪子,所以其實 CSV 檔案的操作可以考慮使用FileHelpers 之類的套件來處理,這邊只是為了練習一下委派的用法來示例
Sample Code:GitHub
測試連線資料庫的數據
想要測試在不同的連線環境(固網、WIFI、VPN…Etc)之下,連線資料庫的速度
所以寫了這個小程式,還挺適合用委派的
internal class Program
{
public static void Main(string[] args)
{
const int times = 100;
var items = new Dictionary<string, Func<long>>
{
{"MsSql", MsSql},
{"MariaDB", MariaDb},
{"Oracle", Oracle},
};
foreach (var item in items)
{
PrintResult(LoopWorks(item.Value, times), item.Key);
}
}
private static void PrintResult((long, decimal, int) job, string title)
{
Console.WriteLine($"{title} 執行 {job.Item3} 次資料存取,總計花費 {job.Item1:N1} ms,平均 {job.Item2} ms");
}
private static (long, decimal, int) LoopWorks(Func<long> works, int times)
{
long total = 0;
for (var i = 1; i <= times; i++)
{
var speed = works.Invoke();
total += speed;
}
return (total, Math.Round((decimal) total / times, 2), times);
}
private static long MsSql()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var source = new MsSqlAdapter().GetTestData();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
private static long MariaDb()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var source = new MariaDbAdapter().GetTestData();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
private static long Oracle()
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var source = new OracleAdapter().GetTestData();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
}