<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          C# 9.0 新特性預(yù)覽 - init-only 屬性

          共 2026字,需瀏覽 5分鐘

           ·

          2020-10-30 04:39

          前言

          隨著 .NET 5 發(fā)布日期的日益臨近,其對應(yīng)的 C# 新版本已確定為 C# 9.0,其中新增加的特性(或語法糖)也已基本鎖定,本系列文章將向大家展示它們。

          目錄

          [C# 9.0 新特性預(yù)覽 - 類型推導(dǎo)的 new]
          [C# 9.0 新特性預(yù)覽 - 空參數(shù)校驗]
          [C# 9.0 新特性預(yù)覽 - 頂級語句]
          [C# 9.0 新特性預(yù)覽 - init-only 屬性]
          [C# 9.0 新特性預(yù)覽 - Record 類型]
          [C# 9.0 新特性預(yù)覽 - 模式匹配的改善]
          [C# 9.0 新特性預(yù)覽 - 源代碼生成器]
          [C# 9.0 新特性預(yù)覽 - 其他小的變化]

          只初始化 setter (Init Only Setters)

          這個特性允許創(chuàng)建只初始化(init only)的屬性和索引器,使得 C# 中的不可變模型更加靈活。

          背景

          在此之前,我們創(chuàng)建實體類/POCO類/DTO類等等模型類的時候,都期望屬性只讀不允許從外部修改,會將屬性的 setter 設(shè)為私有或者干脆不設(shè)置 setter,例如:

          public class Person
          {
          public string Name { get; private set; }
          // OR
          //public string Name { get; }
          }

          再添加一個擁有全部屬性作為簽名的構(gòu)造方法:

          ...
          public Person(string name)
          {
          this.Name = name;
          }
          ...

          這樣做雖然可以達到目的,但是帶來了兩個問題
          1.假如屬性增多,會帶來工作量的成倍增加,以及不易維護
          2.無法使用對象初始化器(object initializers)

          var person = new Person
          {
          Name = "Rwing" // Compile Error
          };

          在這個情況下,init 關(guān)鍵字應(yīng)運而生了。

          語法

          語法很簡單,只需要將屬性中的 set 關(guān)鍵字替換為 init 即可:

          public string Name { get; init; }

          以上代碼會被大致翻譯為:

          private readonly string _name;
          public string Name
          {
          get { return _name; }
          set { _name = value;}
          }

          可以看到,與 set 的區(qū)別是,init 會為背后的字段添加 readonly 關(guān)鍵字。
          這樣我們就可以去掉一堆屬性的構(gòu)造方法轉(zhuǎn)而使用對象初始化器了,并且達到了不可變的目的。

          var person = new Person
          {
          Name = "Rwing"
          };
          // 初始化后無法再次修改
          person.Name = "Foo"; // Error: Name is not settable

          這一語法,有很多場景需要配合同樣在 C# 9.0 中新增的 record 類型使用。

          哪些情況下可以被設(shè)置

          • 通過對象初始化器

          • 通過 with 表達式

          • 在自身或者派生類的構(gòu)造方法中

          • 在標(biāo)記為 init 的屬性中

          • 在特性(attribute)類的命名參數(shù)屬性中

          以上場景不難理解,但是值得一提的是,只有 get 的屬性是不可以派生類的構(gòu)造方法中賦值的,但是 init 可以:

          class Base
          {
          public bool Foo { get; init; }
          public bool Bar { get; }
          }

          class Derived : Base
          {
          Derived()
          {
          Foo = true;
          Bar = true; // ERROR
          }
          }

          此外有一種例外, 在以上場景中的 lambda 或本地函數(shù)中,也不允許被設(shè)置,例如:
          原因也很簡單,lambda 或本地函數(shù)在編譯后已經(jīng)不在構(gòu)造函數(shù)中了。

          public class Class
          {
          public string Property { get; init; }

          Class()
          {
          System.Action a = () =>
          {
          Property = null; // ERROR
          };
          local();
          void local()
          {
          Property = null; // ERROR
          }
          }
          }

          參考

          [Proposal: Init Only Setters]
          [InitOnlyMemberTests.cs]


          瀏覽 36
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  97操碰| 97超碰人人模人人爱 | www.色大屌 | 天天摸天天肏 | 久久久久久久久久97 |