C#學習 [型別系統] 記錄(14)

huiy_小溪發表於2024-10-30

要求

C#9.0.

概念

記錄是一個類或結構,它為使用資料模型提供特定的語法和行為。

使用場景

  • 想要定義依賴值相等性的資料模型。

例如:想要判斷兩個物件例項值是否想等,這個時候用record就更加合適。

  • 想要定義物件不可變的型別。

值相等性

值相等性是指如果記錄型別的兩個變數型別相匹配,且所有屬性和欄位值都相同,那麼記錄型別的兩個變數是相等的。

不可變性

不可變型別會阻止你在物件例項化後更改該物件的任何屬性或欄位值。

與類和結構的區別

宣告和例項化類或結構時使用的語法與操作記錄時的相同。 只是將 class 關鍵字替換為 record,或者使用 record struct 而不是 struct。 同樣地,記錄類支援相同的表示繼承關係的語法。

  1. 記錄與類的區別如下所示:
  • 可在主建構函式中使用位置引數來建立和例項化具有不可變屬性的型別。
  • 在類中指示引用相等性或不相等的方法和運算子(例如 Object.Equals(Object) 和 ==)在記錄中指示值相等性或不相等。
  • 可使用 with 表示式對不可變物件建立在所選屬性中具有新值的副本。
  • 記錄的 ToString 方法會建立一個格式字串,它顯示物件的型別名稱及其所有公共屬性的名稱和值。
  • 記錄可從另一個記錄繼承。 但記錄不可從類繼承,類也不可從記錄繼承。
  1. 記錄結構與結構的不同之處是,編譯器合成了方法來確定相等性和 ToString。 編譯器為位置記錄結構合成 Deconstruct 方法。

示例

  1. 定義一個record
public record Person(string FirstName, string LastName);

public static class Program
{
    public static void Main()
    {
        Person person = new("Nancy", "Davolio");
        Console.WriteLine(person);
        // output: Person { FirstName = Nancy, LastName = Davolio }
    }

}
  1. 值相等性
public record Person(string FirstName, string LastName, string[] PhoneNumbers);
public static class Program
{
    public static void Main()
    {
        var phoneNumbers = new string[2];
        Person person1 = new("Nancy", "Davolio", phoneNumbers);
        Person person2 = new("Nancy", "Davolio", phoneNumbers);
        // 判斷值是否相等
        Console.WriteLine(person1 == person2); // output: True
        // 改變了person1.PhoneNumbers[0],person2也是引用這個,所以結果想等
        person1.PhoneNumbers[0] = "555-1234";
        Console.WriteLine(person1 == person2); // output: True
        // 判斷引用是否想等,肯定不是!
        Console.WriteLine(ReferenceEquals(person1, person2)); // output: False
    }
}
  1. with表示式改變其中一個屬性
public record Person(string FirstName, string LastName)
{
    public required string[] PhoneNumbers { get; init; }
}

public class Program
{
    public static void Main()
    {
        Person person1 = new("Nancy", "Davolio") { PhoneNumbers = new string[1] };
        Console.WriteLine(person1);
        // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }

        Person person2 = person1 with { FirstName = "John" };
        Console.WriteLine(person2);
        // output: Person { FirstName = John, LastName = Davolio, PhoneNumbers = System.String[] }
        Console.WriteLine(person1 == person2); // output: False

        person2 = person1 with { PhoneNumbers = new string[1] };
        Console.WriteLine(person2);
        // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }
        Console.WriteLine(person1 == person2); // output: False

        person2 = person1 with { };
        Console.WriteLine(person1 == person2); // output: True
    }
}

相關文章