在 C# 講到 Object-Object Mapping,AutoMapper 絕對是在解決方案清單的前幾名,也是我推薦的首選,不過如果我們只是偶爾在程式的某個小角落,需要把一個類別對應成另一個類別,這時候我們可能不會想要去安裝 AutoMapper、寫 Mapping Configuration,會想說是不是有一個更輕量的方法來解決我們當前的問題?
[料理佳餚] 用 SemaphoreSlim 來做 async/await 的鎖定
在 C# 應用程式內部要做鎖定,第一時間我們一定是先想到 lock 陳述式,但是 lock 陳述式無法在 async/await 的場景下使用,程式編譯不會通過,我們會得到一個錯誤訊息 - 無法在 lock 陳述式的主體中等候
。
[小菜一碟] C# 的 double 在 SQL Server 應該要存成 float,搞清楚單精度跟雙精度的差別。
SQL Server 的資料型別中有一個 float
,這個 float 在 C# 對應的應該是 double,而 C# 的 float 對應的 SQL Server 資料型別應該是 real
,那如果將 real 對應成 C# 的 double 會發生什麼事? 答案是小數點的精準度會跑掉。
[廚餘回收] 中了一個 C# 模式比對(Pattern Matching)var 的陷阱
C# 從 7.0 開始加入了模式比對(Pattern Matching),最大的改變是將 switch 從常數比對中解放,讓 switch 可以比對運算式,到了 C# 8.0 更猛了,微軟弄了一個遞迴模式比對(Recursive Pattern Matching),大括號 "{}" 及小括號 "()" 寫到你不要不要的,但是模式比對裡面藏了一個 var
的陷阱,我就踩中了。
[小菜一碟] Trim() 不只能修剪空白字元而已
我們平常在做字串修剪的時候,一定會常用到 Trim() 方法,我們通常拿它來修剪一串字串的前後空白字元,相同的家族成員還有 TrimStart() 及 TrimEnd(),如果我們還想修剪掉其他字元,我們可以使用 Trim(Char[]) 這個多載方法,但是 Trim() 方法不是只能修剪空白字元而已。
[料理佳餚] Dapper 用起來很友善,但是預設的參數型別對執行計劃不太友善。
用過 Dapper 的朋友應該對它是愛不釋手,最近在一個對效能敏感的系統上 tune SQL 查詢語句時,發現到 SQL 參數型別的不同及使不使用 SQL 參數,對執行計劃的選擇影響甚大,相同的查詢條件及結果,只因改了參數的型別,執行計劃就跟著改變,查詢成本也跟著拉高。
[料理佳餚] C# 泛型類別條件約束 where 無法約束帶有參數的建構式怎麼辦?
公司內的一個系統的開發風格轉變,Data Model 必須設計成 Immutable(不可變)的類別,其中一部分會被用在泛型上,由於 Immutable 類別是不能有無參數建構式的,所以被用在泛型的時候,它就不能用 where 進行 new() 的條件約束,沒辦法做 new() 的條件約束,就無法呼叫泛型類別的建構式來產生 Instance,著實困擾。
[料理佳餚] System.IO.Pipelines 解決了以往接收 NetworkStream 算位置的困擾
微軟官方部落格在去年發佈了一篇 System.IO.Pipelines: High performance IO in .NET,這個東西高不高效我是比較不出來,但是它著實解決了以往在接收 NetworkStream 時算位置的困擾,用它寫出來的程式碼簡潔清晰許多。
[小菜一碟] C# 中的奇門遁甲 - 隱含轉換(implicit)
在 C# 中常常因為需要配合參數而動態地產生相對應的 SQL 查詢條件字串,StringBuilder 應該是公認能兼顧字串串接效能的解法,不過加號(+)還真是好用啊!相較於使用 StringBuilder,用加號來串接字串簡單又直接,因此我利用隱含轉換(implicit)來搞一個用加號串接字串,但背後其實是 StringBuilder 的解法。
[小菜一碟] C# 中一個古老的好物 - TypeConverter
TypeConverter 是從 .NET Framework 1.1 開始就有的東西,我是在 ASP.NET MVC 的 ActionFilter 中要取得某個 RouteData 時用到這個東西,它能夠幫助我們取得某個型別的轉換器,用來將另一個型別的實例轉換成該型別,這些型別或許我們在開發時間是未知的,但是在執行時期是明確的。