C# 9.0的init訪問器

不控制可變性

下面是我們最常見的屬性聲明方式,允許屬性在類的內部和外部都可以讀取和修改

public int Id { get; set; }
namespace Demo
{public class Company{public int Id { get; set; }public Company(){}public Company(int id){Id = id; // 可以在構造函數中設置}public void UpdateId(int newId){Id = newId; // 可以在類內部的方法中修改}}internal class Program{static void Main(string[] args){var company = new Company(1);Console.WriteLine(company.Id); // 輸出:1company.Id = 2; // 可以在類外部修改Console.WriteLine(company.Id); // 輸出:2// 使用對象初始化器語法,需要無參數構造函數var newCompany = new Company { Id = 6 };Console.WriteLine(newCompany.Id); // 輸出:6newCompany.UpdateId(4); // 通過方法更新Console.WriteLine(newCompany.Id); // 輸出:4}}
}

數據一致性問題:在某些情況下,屬性不應該在對象生命周期內被隨意修改。例如,Id屬性通常用于唯一標識一個對象,如果允許在對象生命周期內修改它,可能導致數據不一致的問題

去掉set訪問器

去掉set訪問器,使得屬性變為只讀

namespace Demo
{public class Company{public int Id { get; }public Company(){}public Company(int id){Id = id; // 只能在構造函數中設置}// UpdateId 方法不能再修改 Id 屬性,因為 get 訪問器限制了修改// public void UpdateId(int newId)// {//     Id = newId; // 編譯錯誤:不能修改只讀屬性// }}internal class Program{static void Main(string[] args){var company = new Company(1);Console.WriteLine(company.Id); // 輸出:1// 下面這行代碼會導致編譯錯誤,因為 Id 屬性是只讀的// company.Id = 2; // 編譯錯誤:不能修改只讀屬性// 下面這行代碼會導致編譯錯誤,因為對象初始化器不能設置只讀屬性// var newCompany = new Company { Id = 6 }; // 編譯錯誤:不能使用對象初始化器設置只讀屬性var newCompany = new Company(6);Console.WriteLine(newCompany.Id); // 輸出:6// newCompany.UpdateId(4); // 編譯錯誤:不能修改只讀屬性// Console.WriteLine(newCompany.Id); // 輸出:4}}
}

readonly

readonly指示只能在聲明期間或在同一個類的構造函數中向字段賦值。 可以在字段聲明和構造函數中多次分配和重新分配只讀字段

namespace Demo
{public class Company{public readonly int Id = 666; // 使用 readonly 關鍵字,初始化默認值為 666public Company(){// 無參數構造函數使用默認值 666}public Company(int id){Id = id; // 可以在構造函數中設置新的值}// UpdateId 方法不能再修改 Id 字段,因為 readonly 限制了修改// public void UpdateId(int newId)// {//     Id = newId; // 編譯錯誤:readonly 字段只能在構造函數中賦值// }}internal class Program{static void Main(string[] args){var initCompany = new Company();Console.WriteLine(initCompany.Id); // 輸出:666var company = new Company(1);Console.WriteLine(company.Id); // 輸出:1// 下面這行代碼會導致編譯錯誤,因為 Id 字段是只讀的// company.Id = 2; // 編譯錯誤:readonly 字段在構造函數外不可修改// 使用對象初始化器時不能設置 readonly 字段,因此需要使用構造函數// var newCompany = new Company { Id = 6 }; // 編譯錯誤:readonly 字段不能使用對象初始化器設置}}
}

private

如果不想在類外部修改,我們也可以這樣寫

namespace Demo
{public class Company{public int Id { get; private set; }public Company() { }public Company(int id){Id = id;  // 可以在構造函數中設置}public void UpdateId(int newId){Id = newId;  // 可以在類內部的方法中修改}}internal class Program{static void Main(string[] args){var company = new Company(1);Console.WriteLine(company.Id); //輸出:1company.UpdateId(4);Console.WriteLine(company.Id); // 輸出:4var newCompany = new Company();//company.Id = 2; // 編譯錯誤:外部不能修改}}
}

private set訪問器,允許類內部修改屬性,但外部不可修改,即保護內部狀態,常見應用場景:計數器、狀態管理等

init訪問器

init訪問器允許屬性在對象初始化時設置,但在對象初始化完成后就不能再修改

using System;namespace Demo
{public class Company{public int Id { get; init; } // 使用 init 訪問器,使得屬性在初始化后不可修改public Company(){}public Company(int id){Id = id; // 可以在構造函數中設置}// UpdateId 方法不能再修改 Id 屬性,因為 init 訪問器限制了修改// public void UpdateId(int newId)// {//     Id = newId; // 編譯錯誤:初始化后不可修改// }}internal class Program{static void Main(string[] args){var company = new Company(1);Console.WriteLine(company.Id); // 輸出:1// 下面這行代碼會導致編譯錯誤,因為 Id 屬性是只讀的// company.Id = 2; // 編譯錯誤:初始化后不可修改var newCompany = new Company { Id = 3 }; // 使用對象初始化器Console.WriteLine(newCompany.Id); // 輸出:3// 下面這行代碼會導致編譯錯誤,因為 Id 屬性是只讀的// newCompany.Id = 4; // 編譯錯誤:初始化后不可修改}}
}

init訪問器在數據傳輸對象(DTO)和配置對象中的應用

數據傳輸對象(DTO)

數據傳輸對象(DTO)是用于在不同系統或不同層之間傳遞數據的簡單對象。這些對象通常不包含任何業務邏輯,僅用于封裝數據。使用init訪問器可以確保DTO在創建后其屬性不會被修改,從而保證傳輸數據的完整性和一致性

namespace Demo
{public class CustomerDto{public int Id { get; init; }public string Name { get; init; }public string Email { get; init; }}internal class Program{static void Main(string[] args){// 使用對象初始化器創建DTO實例var customer = new CustomerDto{Id = 1,Name = "John Doe",Email = "john.doe@example.com"};Console.WriteLine($"Customer: {customer.Id}, {customer.Name}, {customer.Email}"); // 輸出:Customer: 1, John Doe, john.doe@example.com// customer.Name = "Jane Doe"; // 編譯錯誤:初始化后不可修改}}
}

配置對象

配置對象通常用于存儲應用程序的配置設置。這些設置在應用程序啟動時加載,并在整個應用程序生命周期內保持不變。使用init訪問器可以確保配置對象在初始化后,其配置屬性不會被修改,從而防止在應用程序運行過程中意外更改配置

public class AppConfig
{public string ConnectionString { get; init; }public int MaxRetryCount { get; init; }public bool EnableLogging { get; init; }
}internal class Program
{static void Main(string[] args){// 使用對象初始化器創建配置對象實例var config = new AppConfig{ConnectionString = "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;",MaxRetryCount = 5,EnableLogging = true};// 輸出:Config: ConnectionString=Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;, MaxRetryCount=5, EnableLogging=TrueConsole.WriteLine($"Config: ConnectionString={config.ConnectionString}, MaxRetryCount={config.MaxRetryCount}, EnableLogging={config.EnableLogging}");// config.MaxRetryCount = 10; // 編譯錯誤:初始化后不可修改}
}

開始使用init訪問器

在C#9.0中,引入了init訪問器。使用此功能,有兩個先決條件:

  1. 安裝.NET 5+ SDK
  2. 安裝Visual Studio 2019或更高版本

參考

  • C# Init-Only Setters 屬性 — C# Init-Only Setters Property (loginradius.com)
  • C#中init()方法是起什么作用啊-CSDN社區
  • init 關鍵字 - C# reference | Microsoft Learn
  • 一看就懂——C#中readonly關鍵字_c# readonly關鍵字-CSDN博客
  • 只讀關鍵字 - C# reference | Microsoft Learn
  • C#9.0:Init - Hello-Brand - 博客園 (cnblogs.com)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18503.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18503.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18503.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

22.Volatile原理

文章目錄 Volatile原理1.Volatile語義中的內存屏障1.1.volatile寫操作的內存屏障1.1.1.StoreStore 屏障1.1.2.StoreLoad 屏障 1.2.volatile讀操作的內存屏障1.2.1.LoadStore屏障1.2.2.LoadLoad屏障 2.volatile不具備原子性2.1.原理 Volatile原理 1.Volatile語義中的內存屏障 在…

用于生成 Avatar 的文本引導式情感和運動控制-InstructAvatar

網址 https://wangyuchi369.github.io/InstructAvatar/ 用于生成 Avatar 的文本引導式情感和運動控制 官網翻譯 最近的會說話的頭像生成模型在實現與音頻的真實和準確的嘴唇同步方面取得了長足的進步,但在控制和傳達頭像的詳細表情和情感方面往往存在不足&#…

APM2.8如何做加速度校準

加速度的校準建議準備一個六面平整,邊角整齊的方形硬紙盒或者塑料盒,如下圖所示,我們將以它作為APM校準時的水平垂直姿態參考,另外當然還需要一塊水平的桌面或者地面 首先用雙面泡沫膠或者螺絲將APM主板正面向上固定于方形盒子上&…

JavaScrip原型對象

參考 JavaScrip原型對象 | LogDicthttps://www.logdict.com/archives/javascripyuan-xing-mo-shi

每天寫兩道(二)LRU緩存、

146.LRU 緩存 . - 力扣(LeetCode) 請你設計并實現一個滿足 LRU (最近最少使用) 緩存 約束的數據結構。 實現 LRUCache 類: LRUCache(int capacity) 以 正整數 作為容量 capacity 初始化 LRU 緩存int get(int key) 如果關鍵字 key 存在于緩存…

如何使用Python和大模型進行數據分析和文本生成

如何使用Python和大模型進行數據分析和文本生成 Python語言以其簡潔和強大的特性,成為了數據科學、機器學習和人工智能開發的首選語言之一。隨著大模型(Large Language Models, LLMs)如GPT-4的崛起,我們能夠利用這些模型實現諸多…

Revit——(2)模型的編輯、軸網和標高

目錄 一、關閉縮小的隱藏窗口 二、標高(可創建平面,其他標高線復制即可) 三、軸網 周圍的四個圈和三角表示四個里面,可以移動,不要刪除 一、關閉縮小的隱藏窗口 二、標高(可創建平面,其他標…

計算機體系結構期末快速復習

文章目錄 前言CPI,MIPS(大題1)加速比(大題2)流水線(大題3)CRAY-1向量機(大題4)Tomasulo算法(大題5)概念簡答題計算機系統結構的經典定義什么是透明…

深入分析 Android Activity (二)

文章目錄 深入分析 Android Activity (二)1. Activity 的啟動模式(Launch Modes)1.1 標準模式(standard)1.2 單頂模式(singleTop)1.3 單任務模式(singleTask)1.4 單實例模式&#xf…

利用邊緣計算網關的工業設備數據采集方案探討-天拓四方

隨著工業4.0時代的到來,工業設備數據采集成為了實現智能制造、提升生產效率的關鍵環節。傳統的數據采集方案往往依賴于中心化的數據處理方式,但這種方式在面對海量數據、實時性要求高的工業場景時,往往顯得力不從心。因此,利用邊緣…

CSS實現一個雨滴滑落效果

使用純CSS來實現一個真實的雨滴滑落效果可能會有些挑戰,因為CSS主要關注于靜態樣式和簡單的動畫效果。然而,你可以使用CSS動畫和keyframes來模擬一個雨滴滑落的簡化效果。 以下是一個基本的示例,展示如何使用CSS來模擬雨滴從頂部滑落到底部的…

AI學習指南數學工具篇-MATLAB中的凸優化工具

AI學習指南數學工具篇-MATLAB中的凸優化工具 在人工智能領域,凸優化是一個非常重要的數學工具,它在機器學習、深度學習、數據分析等領域都有著廣泛的應用。而MATLAB作為一款強大的數學工具軟件,提供了豐富的凸優化工具和函數,為用…

二叉樹的鏈式結構(二叉樹)與順序結構(堆)---數據結構

一、樹的概念與結構 1、樹的概念 樹是一種非線性的數據結構,它是由n(n>0)個有限結點組成一個具有層次關系的集合。我們常把它叫做樹,是因為它看起來像一棵倒掛的樹,它的根是朝上的,而葉是朝下的。 下面…

給我一個用斷言結果執行下一步的例子

在使用 pytest 和 Selenium 進行自動化測試時,通常我們會根據斷言的結果來決定測試流程的走向。如果斷言失敗,測試通常會停止執行后續的步驟,因為失敗意味著被測系統沒有按照預期工作。然而,有時候我們可能需要在斷言失敗后執行特…

每日復盤-20240528

今日重點關注: 20240528 六日漲幅最大: ------1--------300956--------- 英力股份 五日漲幅最大: ------1--------301361--------- 眾智科技 四日漲幅最大: ------1--------301361--------- 眾智科技 三日漲幅最大: ------1--------301361--------- 眾智科技 二日漲…

前端編程語言——JS背景知識、JS基礎語法、算數運算符和關系運算符(1)

0、前言: JS全稱是JavaScript,是一種腳本語言,誕生于1995年,JS是由ECMAScript(包含js語法)、BOM(Brower Oject Model,和瀏覽器相關操作)、DOM(Document Obje…

ubuntu設置中文輸入法教程

在 Ubuntu 上設置中文輸入法可以通過以下步驟來完成。我們將以安裝和配置 fcitx 輸入法框架及其中文輸入法插件 fcitx-sunpinyin 為例。 ### 步驟一:安裝 fcitx 和中文輸入法插件 1. **更新軟件包列表** 打開終端并運行以下命令來更新軟件包列表: …

淺談—“文件映射”

目錄 文件映射頭文件&#xff1a; 核心函數 port flags 文件映射頭文件&#xff1a; #include<sys/mman.h> 核心函數 void *mmap(void *addr,size_t length, int port,int flags,int fd, off_t offset ); int munmap(void *addr,size_t length);// 對比free&#x…

聯邦和反射器實驗

拓撲圖 一.實驗要求 1.AS1存在兩個環回&#xff0c;一個地址為192.168.1.0/24&#xff0c;該地址不能在任何協議中宣告 AS3存在兩個環回&#xff0c;一個地址為192.168.2.0/24&#xff0c;該地址不能在任何協議中宣告 AS1還有一個環回地址為10.1.1.0/24&#xff…

PyTorch訓練關鍵點

1.背景 在網上找了一些資料用來訓練關鍵點&#xff0c;一般都是人臉或者車牌關鍵點訓練&#xff0c;或者是聯合檢測一起訓練。很少有是單獨基于輕量級網絡訓練單獨關鍵點模型的工程&#xff0c;本文簡單介紹一種簡單方法和代碼。 2.代碼模塊 &#xff08;1&#xff09;網絡結…