利用動態型別與匿名型別來記錄、描述資料
前陣子經手一個與自己毫不相關的案子,裡面有一個需求是必須在運作過程中建立可查詢的物件列表,例如:
鍵值:王小明
資料:該員英文姓名、戶籍地址...
鍵值:李小華
資料:該員英文姓名、戶籍地址...
依據正規的作法應該是建立一個集合物件,然後定義成員資料DTO,接著逐一添加進入這個集合物件。但,由於這不是一個後續會永久維護的案子,我也不想在這個案子中貢獻過多的程式碼,因此思考著如何在不建立Model Class的狀態,也不考慮效能的狀態下,來撰寫這些程式碼。
透過動態型別與匿名型別來儲存資料至記憶體
先說好,這裡不考慮效能,只考慮以最短的時間內將資料以可查詢的型態記錄在記憶體中,供給後續查詢或輸出利用。
//宣告一個動態物件
var oDynamic = new System.Dynamic.ExpandoObject();
//製作資料
for (int i = 0; i < 5; i++)
{ //宣告動態物件是字典介面,並利用Add方法推入鍵值與資料包
(oDynamic as System.Collections.Generic.IDictionary<string, object>)
.Add($"cKey{i}", new { cId = $"User{i}", iMoney = i });
}
序列化輸出成JSON
透過Json.NET驗證資料是否可以序列化輸出,丟給外部處理:
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(oDynamic, Newtonsoft.Json.Formatting.Indented));
答案是可以的:
{
"cKey0": {
"cId": "User0",
"iMoney": 0
},
"cKey1": {
"cId": "User1",
"iMoney": 1
},
"cKey2": {
"cId": "User2",
"iMoney": 2
},
"cKey3": {
"cId": "User3",
"iMoney": 3
},
"cKey4": {
"cId": "User4",
"iMoney": 4
}
}
在程式碼中動態取值
假設我們要針對cKey2拿出裡面的資料包與值,那麼我們可以反宣告回dynamic型別,就可以順利的轉型回來,超爽的。
dynamic oTemp = (oDynamic as System.Collections.Generic.IDictionary<string, object>)["cKey2"];
Console.WriteLine(oTemp.cId);
Console.WriteLine(oTemp.iMoney);
上面描述的做法其實並不正規,對於效能的損耗也很大(效能超低),閱讀者可以發現其實在「動態取值」階段程式碼已經開始變得失控(會有一種乾脆把資料類別定義好不是比較乾脆嗎?的想法),使用者請自己視情況判斷是否採用之。對於我來說,應用其實到輸出階段就終止了,所以我還蠻偏好這種寫法的。