iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0

昨天講到了不可變的集合,今天再介紹C#中另一個具有不可變特性的的元素-Record,進入用C#寫FP的重點了!

基本介紹

  1. 如何建立一個Record

    // 跟class一樣可以設定欄位屬性,可以設定欄位的的存取層級(public/private)
    public record Person
    {
        public string FirstName { get; init; } 
        public string LastName { get; init; } 
    };
    
    // 也可以寫成位置屬性,搭配pattern match的position pattern解構很方便
    public record Person(string FirstName, string LastName);
    
    // 可同時具有位置屬性與欄位屬性
    public record Person(string FirstName, string LastName)
    {
        public string[] PhoneNumbers { get; init; } = Array.Empty<string>();
    
    		// 也可以具有方法
    		public bool HasPhoneNumbers => PhoneNumbers.Any()
    };
    
  2. 如果用位置屬性的方式宣告,就具有不變性,但是欄位屬性仍能夠設定成{get;set;},也就是可變得

  3. 直接幫你實做了IEquatable<T>

    // 原來的類別
    class PersonClass
    {
    		public string name { get; set; }
    }
    
    var person1 = new PersonClass { name = "安妮雅" };
    var person2 = new PersonClass { name = "安妮雅" };
    Console.WriteLine(person1 == person2 );
    // false,兩個person參考的物件實際上不同
    
    // 使用record
    record PersonRecord(string name)
    PresonRecord person3 = new("約兒"); 
    PresonRecord person4 = new("約兒"); 
    Console.WriteLine(person3 == person4 );
    // true,record有實作
    
  4. 可以繼承

    public abstract record Person(string FirstName, string LastName);
    public record Doctor(string FirstName, string LastName)
        : Person(FirstName, LastName);
    public record Spy(string FirstName, string LastName)
        : Person(FirstName, LastName);
    public static void Main()
    {
        Person doctor = new Doctor("洛伊德", "佛傑");
        Person spy = new Spy("洛伊德", "佛傑");
        Console.WriteLine(doctor == spy); 
        // False
    }
    
  5. 如果想要創造一個新的實例,而且內容跟原來只有一點點差異可以使用with

    public record Person(string FirstName, string LastName)
    Person person1 = new("洛伊德", "佛傑");
    Console.WriteLine(person1);
    // output: Person { FirstName = "洛伊德", LastName = "佛傑" }
    
    Person person2 = person1 with { FirstName = "約兒" };
    Console.WriteLine(person2);
    // output: Person { FirstName = "約兒", LastName = "佛傑" }
    

小結

Record其實是class的語法糖,C#在背後默默的幫你時做了不變性以及可比較,在OO語言裡面比較常看到作為value object使用。在一開始的地方有提到Record可以具有方法成員,但其實不建議,在FP的風格中我們會把資料與行為分開來,而方法會放在模組(module)中,C#中對應到可以用Record(資料)與靜態類別(模組)。明天會進一步介紹Record的使用方法


上一篇
Day10. ImmutableCollection
下一篇
Day12. Record(2)
系列文
Functional Programming with C#30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言