C#9.0中init訪問(wèn)器的實(shí)現(xiàn)
不控制可變性
下面是我們最常見的屬性聲明方式,允許屬性在類的內(nèi)部和外部都可以讀取和修改
public int Id { get; set; }
namespace Demo { public class Company { public int Id { get; set; } public Company() { } public Company(int id) { Id = id; // 可以在構(gòu)造函數(shù)中設(shè)置 } public void UpdateId(int newId) { Id = newId; // 可以在類內(nèi)部的方法中修改 } } internal class Program { static void Main(string[] args) { var company = new Company(1); Console.WriteLine(company.Id); // 輸出:1 company.Id = 2; // 可以在類外部修改 Console.WriteLine(company.Id); // 輸出:2 // 使用對(duì)象初始化器語(yǔ)法,需要無(wú)參數(shù)構(gòu)造函數(shù) var newCompany = new Company { Id = 6 }; Console.WriteLine(newCompany.Id); // 輸出:6 newCompany.UpdateId(4); // 通過(guò)方法更新 Console.WriteLine(newCompany.Id); // 輸出:4 } } }
數(shù)據(jù)一致性問(wèn)題:在某些情況下,屬性不應(yīng)該在對(duì)象生命周期內(nèi)被隨意修改。例如,Id屬性通常用于唯一標(biāo)識(shí)一個(gè)對(duì)象,如果允許在對(duì)象生命周期內(nèi)修改它,可能導(dǎo)致數(shù)據(jù)不一致的問(wèn)題
去掉set訪問(wèn)器
去掉set訪問(wèn)器,使得屬性變?yōu)橹蛔x
namespace Demo { public class Company { public int Id { get; } public Company() { } public Company(int id) { Id = id; // 只能在構(gòu)造函數(shù)中設(shè)置 } // UpdateId 方法不能再修改 Id 屬性,因?yàn)?get 訪問(wèn)器限制了修改 // public void UpdateId(int newId) // { // Id = newId; // 編譯錯(cuò)誤:不能修改只讀屬性 // } } internal class Program { static void Main(string[] args) { var company = new Company(1); Console.WriteLine(company.Id); // 輸出:1 // 下面這行代碼會(huì)導(dǎo)致編譯錯(cuò)誤,因?yàn)?Id 屬性是只讀的 // company.Id = 2; // 編譯錯(cuò)誤:不能修改只讀屬性 // 下面這行代碼會(huì)導(dǎo)致編譯錯(cuò)誤,因?yàn)閷?duì)象初始化器不能設(shè)置只讀屬性 // var newCompany = new Company { Id = 6 }; // 編譯錯(cuò)誤:不能使用對(duì)象初始化器設(shè)置只讀屬性 var newCompany = new Company(6); Console.WriteLine(newCompany.Id); // 輸出:6 // newCompany.UpdateId(4); // 編譯錯(cuò)誤:不能修改只讀屬性 // Console.WriteLine(newCompany.Id); // 輸出:4 } } }
readonly
readonly指示只能在聲明期間或在同一個(gè)類的構(gòu)造函數(shù)中向字段賦值。 可以在字段聲明和構(gòu)造函數(shù)中多次分配和重新分配只讀字段
namespace Demo { public class Company { public readonly int Id = 666; // 使用 readonly 關(guān)鍵字,初始化默認(rèn)值為 666 public Company() { // 無(wú)參數(shù)構(gòu)造函數(shù)使用默認(rèn)值 666 } public Company(int id) { Id = id; // 可以在構(gòu)造函數(shù)中設(shè)置新的值 } // UpdateId 方法不能再修改 Id 字段,因?yàn)?readonly 限制了修改 // public void UpdateId(int newId) // { // Id = newId; // 編譯錯(cuò)誤:readonly 字段只能在構(gòu)造函數(shù)中賦值 // } } internal class Program { static void Main(string[] args) { var initCompany = new Company(); Console.WriteLine(initCompany.Id); // 輸出:666 var company = new Company(1); Console.WriteLine(company.Id); // 輸出:1 // 下面這行代碼會(huì)導(dǎo)致編譯錯(cuò)誤,因?yàn)?Id 字段是只讀的 // company.Id = 2; // 編譯錯(cuò)誤:readonly 字段在構(gòu)造函數(shù)外不可修改 // 使用對(duì)象初始化器時(shí)不能設(shè)置 readonly 字段,因此需要使用構(gòu)造函數(shù) // var newCompany = new Company { Id = 6 }; // 編譯錯(cuò)誤:readonly 字段不能使用對(duì)象初始化器設(shè)置 } } }
private
如果不想在類外部修改,我們也可以這樣寫
namespace Demo { public class Company { public int Id { get; private set; } public Company() { } public Company(int id) { Id = id; // 可以在構(gòu)造函數(shù)中設(shè)置 } public void UpdateId(int newId) { Id = newId; // 可以在類內(nèi)部的方法中修改 } } internal class Program { static void Main(string[] args) { var company = new Company(1); Console.WriteLine(company.Id); //輸出:1 company.UpdateId(4); Console.WriteLine(company.Id); // 輸出:4 var newCompany = new Company(); //company.Id = 2; // 編譯錯(cuò)誤:外部不能修改 } } }
private set訪問(wèn)器,允許類內(nèi)部修改屬性,但外部不可修改,即保護(hù)內(nèi)部狀態(tài),常見應(yīng)用場(chǎng)景:計(jì)數(shù)器、狀態(tài)管理等
init訪問(wèn)器
init訪問(wèn)器允許屬性在對(duì)象初始化時(shí)設(shè)置,但在對(duì)象初始化完成后就不能再修改
using System; namespace Demo { public class Company { public int Id { get; init; } // 使用 init 訪問(wèn)器,使得屬性在初始化后不可修改 public Company() { } public Company(int id) { Id = id; // 可以在構(gòu)造函數(shù)中設(shè)置 } // UpdateId 方法不能再修改 Id 屬性,因?yàn)?init 訪問(wèn)器限制了修改 // public void UpdateId(int newId) // { // Id = newId; // 編譯錯(cuò)誤:初始化后不可修改 // } } internal class Program { static void Main(string[] args) { var company = new Company(1); Console.WriteLine(company.Id); // 輸出:1 // 下面這行代碼會(huì)導(dǎo)致編譯錯(cuò)誤,因?yàn)?Id 屬性是只讀的 // company.Id = 2; // 編譯錯(cuò)誤:初始化后不可修改 var newCompany = new Company { Id = 3 }; // 使用對(duì)象初始化器 Console.WriteLine(newCompany.Id); // 輸出:3 // 下面這行代碼會(huì)導(dǎo)致編譯錯(cuò)誤,因?yàn)?Id 屬性是只讀的 // newCompany.Id = 4; // 編譯錯(cuò)誤:初始化后不可修改 } } }
init訪問(wèn)器在數(shù)據(jù)傳輸對(duì)象(DTO)和配置對(duì)象中的應(yīng)用
數(shù)據(jù)傳輸對(duì)象(DTO)
數(shù)據(jù)傳輸對(duì)象(DTO)是用于在不同系統(tǒng)或不同層之間傳遞數(shù)據(jù)的簡(jiǎn)單對(duì)象。這些對(duì)象通常不包含任何業(yè)務(wù)邏輯,僅用于封裝數(shù)據(jù)。使用init訪問(wèn)器可以確保DTO在創(chuàng)建后其屬性不會(huì)被修改,從而保證傳輸數(shù)據(jù)的完整性和一致性
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) { // 使用對(duì)象初始化器創(chuàng)建DTO實(shí)例 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"; // 編譯錯(cuò)誤:初始化后不可修改 } } }
配置對(duì)象
配置對(duì)象通常用于存儲(chǔ)應(yīng)用程序的配置設(shè)置。這些設(shè)置在應(yīng)用程序啟動(dòng)時(shí)加載,并在整個(gè)應(yīng)用程序生命周期內(nèi)保持不變。使用init訪問(wèn)器可以確保配置對(duì)象在初始化后,其配置屬性不會(huì)被修改,從而防止在應(yīng)用程序運(yùn)行過(guò)程中意外更改配置
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) { // 使用對(duì)象初始化器創(chuàng)建配置對(duì)象實(shí)例 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=True Console.WriteLine($"Config: ConnectionString={config.ConnectionString}, MaxRetryCount={config.MaxRetryCount}, EnableLogging={config.EnableLogging}"); // config.MaxRetryCount = 10; // 編譯錯(cuò)誤:初始化后不可修改 } }
開始使用init訪問(wèn)器
在C#9.0中,引入了init訪問(wèn)器。使用此功能,有兩個(gè)先決條件:
- 安裝.NET 5+ SDK
- 安裝Visual Studio 2019或更高版本
參考
- C# Init-Only Setters 屬性 — C# Init-Only Setters Property (loginradius.com)
- C#中init()方法是起什么作用啊-CSDN社區(qū)
- init 關(guān)鍵字 - C# reference | Microsoft Learn
- 一看就懂——C#中readonly關(guān)鍵字_c# readonly關(guān)鍵字-CSDN博客
- 只讀關(guān)鍵字 - C# reference | Microsoft Learn
- C#9.0:Init - Hello-Brand - 博客園 (cnblogs.com)
到此這篇關(guān)于C#9.0中init訪問(wèn)器的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C# init訪問(wèn)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vista和win7在windows服務(wù)中交互桌面權(quán)限問(wèn)題解決方法:穿透Session 0 隔離
服務(wù)(Service)對(duì)于大家來(lái)說(shuō)一定不會(huì)陌生,它是Windows 操作系統(tǒng)重要的組成部分。我們可以把服務(wù)想像成一種特殊的應(yīng)用程序,它隨系統(tǒng)的“開啟~關(guān)閉”而“開始~停止”其工作內(nèi)容,在這期間無(wú)需任何用戶參與2016-04-04關(guān)于C#執(zhí)行順序帶來(lái)的一些潛在問(wèn)題
這篇文章主要給大家介紹了關(guān)于C#執(zhí)行順序帶來(lái)的一些潛在問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08C#中括號(hào)強(qiáng)轉(zhuǎn)、as、is區(qū)別詳解
本文主要介紹了C#中括號(hào)強(qiáng)轉(zhuǎn)、as、is區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02