日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C# 9 record 并非简单属性 POCO 的语法糖

發布時間:2023/12/4 C# 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C# 9 record 并非简单属性 POCO 的语法糖 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近升級專案到大統一 .NET 5 并使用 C#9 語法嘗試改寫套件,發現之前以為 record 只是簡單屬性 POCO 的簡化語法糖的認知是錯誤。

另外因為 POCO 屬于需定義口語詞,這邊在本文定義簡單屬性 POCO?為?public class 類別 {public string ID{get;set}/*略*/}?只有屬性的簡單類別代碼

一. rocord 的確底層是 class,但,不是單純簡單屬性 POCO class
可以看 IL Spy 反編譯程序碼,發現系統幫我們做了很多事

二.?預設生成的是屬性是?{get;init;}?不是?{get;set;},這代表設定值時間點在?constructor(建構式),延伸產生immutable(不可變)特性,也代表 record 預設為thread-safe(線程安全),因為都是取得一樣的值。

所以當你使用 Dapper 類似框架查詢完 POCO 資料,想做修改屬性時會報 CS8852 無法修改錯誤。

三. 預設比較邏輯改變
可以看TimCorey寫的例子,可以看到預設 class 跟 record 的 == 差異,線上測試連結

public class Program {public static void Main(){var record1Obj1 = new record1(FirstName: "Lin", LastName: "WeiHan");var record1Obj2 = new record1(FirstName: "Lin", LastName: "WeiHan");Console.WriteLine(record1Obj1 == record1Obj2);//truevar class1Obj1 = new Class1() { FirstName = "Lin", LastName = "WeiHan" };var class2Obj2 = new Class1() { FirstName = "Lin", LastName = "WeiHan" };Console.WriteLine(class1Obj1 == class2Obj2);//false} }public record record1(string FirstName,string LastName);public class Class1 {public string FirstName {get;init;}public string LastName{get;init;} }

因為 record override?==?跟?Equals,認為只要是同一個 record 類型,并且屬性值都一樣,系統就會認定為true,也就是俗稱的structural equality,可以看 IL Spy 反編譯代碼

public virtual bool Equals(record2? other){return (object)other != null && EqualityContract == other!.EqualityContract && EqualityComparer<string>.Default.Equals(FirstName, other!.FirstName) && EqualityComparer<string>.Default.Equals(LastName, other!.LastName);}

跟 object class 預設會去取得?RuntimeHelpers.GetHashCode?Handle 邏輯不相同。

四. GetHashCode也做了類似邏輯,所以屬性值一樣,HashCode會得到一樣的值,線上測試連結

IL Spy 反編譯代碼

public override int GetHashCode(){return (EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(FirstName)) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(LastName);}

五. 注意不能把 record 當作一定是?immutable(不可變),原因在微軟沒有限制以下寫法...

public record record2 {public string FirstName {get;set;}public string LastName{get;set;} }

準許修改?{get;init;}?為?{get;set},將會導致 immutable 跟 thread-safe 特性消失

六. record 會幫忙生成可讀性好的 ToString 實作
以下圖片為比較一般 class 跟 record 生成的 ToString 差別

七. record 幫忙生成?extend IEquatable<類別>?,并實作強型別public virtual bool Equals(Record1? other)

這代表可以避免原本public override bool Equals(object? obj)需要先 unboxing 再 boxing 的效能損耗問題

閱讀資料:

  • https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9

總結

以上是生活随笔為你收集整理的C# 9 record 并非简单属性 POCO 的语法糖的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。