C#委派練習

一直以來C#委派的語法總是很難搞懂,有一天寫一寫javascript的callback,突然感覺好像就是一樣的東西,似乎也沒那麼難,剛好有時間就找找範例來練習一下

從 CSV 文字檔中讀取紀錄,然後轉成 dto 進行其他操作

  • 方法 A:從檔案中取得資料,逐行執行某些行為
  • 方法 B:將文字轉換為 DTO 實體

為了不要讓某些事情的程式碼寫死在方法 A 裡面,具體的行為應從外部傳入給方法 A,所以透過委派的方式來做

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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)之下,連線資料庫的速度

所以寫了這個小程式,還挺適合用委派的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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;
}
}