Enum - 關於溝通
阿罵 : 要吃水果嗎
我 : 不用
…
阿罵 : 要吃蘋果嗎
我 : 不用,謝謝阿罵
…
阿罵 : 要吃芭樂嗎
我 : 不要
…
阿罵 : 要吃蘋果還是芭樂
我 : (。ŏ_ŏ)
…
…
…
…
我們是否也曾在溝通上感到無力 ? 是否想過為甚麼阿罵總是覺得你要吃水果 ?
其實你知道阿罵只是想跟你聊聊天、想跟你有更多的互動
你的拒絕也不是討厭水果甚至討厭阿罵,你只是當下沒有足夠的耐心與阿罵交流,或是某種程度上是因為溝通成本太高
溝通,是一門藝術,更是一種選擇。
人生中最痛苦的事之一,莫過於你以為你說得很清楚,對方卻完全接收不到對應的資訊。
這樣的錯頻,在程式世界裡也屢見不鮮。
你明明送出了一個清楚的 StatusEnum.Full,卻被序列化成一個看似陌生又難以理解的 2。
又或是,在情感世界裡,你說「我很好」,但其實你需要的是「你懂我」。
真正的溝通,從來不是你說了什麼而已,而是雙方是否都「懂了」。
JSON 序列化與反序列化
假設我們今天定義訂單的結構
1 |
|
恩恩,很棒,接著我們將實體序列化後打 API,發現 API 怎麼都打都不通是怎樣,Debug 時印出 payload 看看才發現..
1 |
|
你傳了 2 過去,你傳了 2 過去! 為什麼?
實際上 Enum 背後仍然是數值,要在序列化與反序列化之間做一些特殊處理才能自然之然的傳出 Member Name
那,我們來試驗看看反序列化吧
1 |
|
結果直接噴掉,因為他找不到對應的型別處理 (Text.Json)
解決這個問題,Json 有出一些好棒棒的工具,解決了你我傳資料的困擾!
- NewtonSoft.Json 提供的 Attribute
1
[ ]
- Text.Json 提供的 Attribute
1
2[ ]
服用方式就是掛在 Property 上 (以 Text.Json 為例)
1
2
3
4
5
6
7
8
9
public class Order
{
public int Id { get; set; }
[ ]
public StatusEnum Status {get;set;}
}
藥效絕佳!
好問題暫時解決了,但作為一個 RD 肯定不會停在這裡對吧,對吧?
我都懂,那我們簡單實驗一下二者可能會有什麼差異呢?
實驗時間
1️⃣ 反序列化時的大小寫處理
1 |
|
結果是成功的,也就是大小寫問題預設都會放寬限制
2️⃣ 字串與數字混用的解析
1 |
|
結果是成功的,也就是用數字也沒問題
3️⃣ 無效值的處理(Invalid Enum Value)
1 |
|
都會好好的噴錯
4️⃣ 反序列化不指定資料呢
1 |
|
結果就是抓預設值,因為它屬於值類型的型別
5️⃣ NewtonSoft 支援 SnakeCase
1 |
|
結果如下
看到這你可能會想,乾 他會幫我切怎樣是正確的英文單字嗎?
當然不是,他會認 “大寫單字”,也就是 PascalCase 的概念,很有趣吧 ~
結語
你以為自己說得夠清楚:「我不用吃水果」,但阿罵聽到的可能是:StatusEnum = WaitingToBeLoved。
我們回傳的是 “Finish”,結果傳出去的是 2,也不難理解為什麼阿罵期待期待可以再多塞一點
我們努力掛上 [JsonConverter],希望程式能更懂人話,但我們卻常常忘了,真實生活中沒有人幫我們轉格式,阿罵沒有 NamingStrategy,卻總試圖理解你這個版本的「狀態碼」。
人生就像是個沒有 schema 的 API,每個人都用自己的版本發 request,也期待對方能正確 decode。
如果我們願意像寫程式那樣,多花一點時間處理錯誤、多加一些備援邏輯、也許就能讓那些「我不要吃水果」但我還是想來看看你的背後訊息,成功被解析成:
阿罵,其實我也想你了。