.NET 幫助

C# Init 關鍵字(開發人員如何使用)

發佈 2024年10月24日
分享:

init 關鍵字C# 9.0 引入了一種新方式來定義類屬性,以創建不可變對象。 在早期版本的 C# 中,屬性通常用於獲取和設定存取子,以讀取和寫取對象欄位。 然而,使用 init,您可以在物件初始化期間將屬性設為可寫,之後則維持唯讀。

本教程將探討使用 C# init 關鍵字的實際範例和情境。IronPDF 庫. 您還將了解傳統屬性設置器之間的關鍵差異(設定)和新的僅初始化設置器。

Init 關鍵字的基本範例

讓我們從一個基本範例開始:

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
var person = new Person
{
    FirstName = "Iron",d
    LastName = "Dev"
};
// person.FirstName = "Jane";  // This will give a compile-time error.
public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
var person = new Person
{
    FirstName = "Iron",d
    LastName = "Dev"
};
// person.FirstName = "Jane";  // This will give a compile-time error.
Public Class Person
	Public Property FirstName() As String
	Public Property LastName() As String
End Class
Private person = New Person With {
	.FirstName = "Iron",
	d LastName = "Dev"
}
' person.FirstName = "Jane";  // This will give a compile-time error.
VB   C#

C# Init 關鍵字(其對開發者的工作原理):圖1 - 由於屬性標記為僅限初始化,IDE 拋出錯誤

在此範例中,FirstName 和 LastName 被標記為只可初始化的屬性。 這意味著它們只能在物件初始化值設置器中被指派。 物件建立之後,企圖更改其數值會導致編譯時錯誤。

為什麼使用 Init 關鍵字?

使用 init 關鍵字的主要原因是在初始化後使物件屬性不可變。 傳統上,您可以將屬性標記為唯讀以實現不可變性。 然而,你通常需要一個接受所有必要值來設置欄位的構造函數,這可能會導致構造函數樣板代碼。 使用初始化器 (init),您可以利用物件初始化器達成相同的目標,而無需撰寫冗長的建構子。

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
    // Without using constructor boilerplate for property initialization
}
var person = new Person
{
    FirstName = "John",
    LastName = "Doe"
};
public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
    // Without using constructor boilerplate for property initialization
}
var person = new Person
{
    FirstName = "John",
    LastName = "Doe"
};
Public Class Person
	Public Property FirstName() As String
	Public Property LastName() As String
	' Without using constructor boilerplate for property initialization
End Class
Private person = New Person With {
	.FirstName = "John",
	.LastName = "Doe"
}
VB   C#

使用僅初始化屬性的物件初始化

使用初始化可以輕鬆地與物件初始化器配合運作。 與其依賴建構函式設定值,您可以在創建物件時直接定義所需的屬性。

public class Point
{
    public int X { get; init; }
    public int Y { get; init; }
}
var point = new Point { X = 10, Y = 20 };
// point.X = 30;  // This will throw a compile-time error
public class Point
{
    public int X { get; init; }
    public int Y { get; init; }
}
var point = new Point { X = 10, Y = 20 };
// point.X = 30;  // This will throw a compile-time error
Public Class Point
	Public Property X() As Integer
	Public Property Y() As Integer
End Class
Private point = New Point With {
	.X = 10,
	.Y = 20
}
' point.X = 30;  // This will throw a compile-time error
VB   C#

這會創建一個簡單且不可變的 Point 類型對象。 請注意,X 和 Y 的值在初始化時設置,後續無法修改。

將初始化與建構函式混合使用

雖然 init 的主要用途是透過物件初始化器來進行物件初始化,但如果需要,你仍然可以使用建構函式。 這在物件創建期間強制執行特定屬性值時特別有用。

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}
public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}
Public Class Person
	Public Property FirstName() As String
	Public Property LastName() As String
	Public Sub New(ByVal firstName As String, ByVal lastName As String)
		Me.FirstName = firstName
		Me.LastName = lastName
	End Sub
End Class
VB   C#

您可以同時使用構造函數和初始化屬性。 這種方法在對象構建後仍然保持不變的同時,具有更大的靈活性。

Init 優於 Private Set 的好處

以前,開發者使用私有設置存取子來限制在類別外部對屬性的修改。

public class Person
{
    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}
public class Person
{
    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}
Public Class Person
	Private privateFirstName As String
	Public Property FirstName() As String
		Get
			Return privateFirstName
		End Get
		Private Set(ByVal value As String)
			privateFirstName = value
		End Set
	End Property
	Private privateLastName As String
	Public Property LastName() As String
		Get
			Return privateLastName
		End Get
		Private Set(ByVal value As String)
			privateLastName = value
		End Set
	End Property
	Public Sub New(ByVal firstName As String, ByVal lastName As String)
		Me.FirstName = firstName
		Me.LastName = lastName
	End Sub
End Class
VB   C#

雖然此方法有效,但需要構造函式樣板程式碼來初始化屬性。 此外,這也允許類本身在後期修改屬性,這對於不可變物件來說並不總是理想的。 init 關鍵字解決了這個問題,因為它僅允許在物件創建時初始化,並在之後阻止任何修改。

使用唯讀欄位和初始化存取器進行初始化處理

在物件創建期間,init 關鍵字可以初始化欄位或屬性,而之後它們保持不變。 雖然唯讀欄位提供不可變性,但初始存取子為屬性提供了類似的功能。 以下是兩種處理不變性的方式:使用唯讀欄位和初始化屬性。

使用唯讀欄位與建構函式

在此示例中,我們使用了唯讀欄位來存放 firstName 和 lastName,這些欄位是在物件建構時設置的。 這些欄位只能在建構函式中被賦值一次,之後不可修改:

public class Person
{
    private readonly string firstName;
    private readonly string lastName;
    public string FirstName => firstName;
    public string LastName => lastName;
    public Person(string firstName, string lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
public class Person
{
    private readonly string firstName;
    private readonly string lastName;
    public string FirstName => firstName;
    public string LastName => lastName;
    public Person(string firstName, string lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
Public Class Person
'INSTANT VB NOTE: The field firstName was renamed since Visual Basic does not allow fields to have the same name as other class members:
	Private ReadOnly firstName_Conflict As String
'INSTANT VB NOTE: The field lastName was renamed since Visual Basic does not allow fields to have the same name as other class members:
	Private ReadOnly lastName_Conflict As String
	Public ReadOnly Property FirstName() As String
		Get
			Return firstName_Conflict
		End Get
	End Property
	Public ReadOnly Property LastName() As String
		Get
			Return lastName_Conflict
		End Get
	End Property
	Public Sub New(ByVal firstName As String, ByVal lastName As String)
		Me.firstName_Conflict = firstName
		Me.lastName_Conflict = lastName
	End Sub
End Class
VB   C#

使用 init 存取器進行初始化

或者,我們可以使用 init 存取器來創建只能在物件創建時進行初始化但之後無法更改的唯讀屬性。 這消除了對唯讀欄位的需求,並提供了一種更現代的語法:

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
Public Class Person
	Public Property FirstName() As String
	Public Property LastName() As String
End Class
VB   C#

IronPDF 介紹

C# Init 關鍵字(對開發人員的運作方式):圖2 - IronPDF:C# PDF 庫

IronPDF是一個為 C# 開發人員設計的強大的 PDF 生成和操作庫。 它簡化了與...的工作將 HTML 轉換為 PDF 文件、CSS、圖片和其他內容轉換成 PDF 文件。 IronPDF 具備像是完美像素渲染、跨平台支持和輕鬆整合到 .NET 專案中的功能,非常適合需要快速生成高品質 PDF 的開發者。 您可以將其用於 .NET Core、Framework 和 Standard,並且它支持包括 Windows、Linux 和 macOS 在內的多種平台。

案例:在 C# 中使用 IronPDF 的 Init 關鍵字

要在 C# 專案中建立不可變物件,並生成 PDF,可以將 init 關鍵字與 IronPDF 結合使用。 初始化關鍵字確保物件在初始化後的完整性,同時IronPDF處理數據並根據該不可變模型生成PDF。

確保在您的項目中正確引用 IronPDF。 您可以透過 NuGet 安裝:

Install-Package IronPdf
Install-Package IronPdf
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'Install-Package IronPdf
VB   C#

以下是程式碼示例:

using IronPdf;
public class Person
{
    public int Id { get; init; }
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
public class PDFGenerator
{
    public static void CreatePersonPDF(Person person)
    {
        var htmlContent = $@"
        <html>
        <body>
            <h1>Person Information</h1>
            <p>ID: {person.Id}</p>
            <p>First Name: {person.FirstName}</p>
            <p>Last Name: {person.LastName}</p>
        </body>
        </html>";
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs($"Person_{person.Id}.pdf");
    }
}
class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Id = 1,
            FirstName = "Iron",
            LastName = "Dev"
        };
        PDFGenerator.CreatePersonPDF(person);
    }
}
using IronPdf;
public class Person
{
    public int Id { get; init; }
    public string FirstName { get; init; }
    public string LastName { get; init; }
}
public class PDFGenerator
{
    public static void CreatePersonPDF(Person person)
    {
        var htmlContent = $@"
        <html>
        <body>
            <h1>Person Information</h1>
            <p>ID: {person.Id}</p>
            <p>First Name: {person.FirstName}</p>
            <p>Last Name: {person.LastName}</p>
        </body>
        </html>";
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs($"Person_{person.Id}.pdf");
    }
}
class Program
{
    static void Main(string[] args)
    {
        var person = new Person
        {
            Id = 1,
            FirstName = "Iron",
            LastName = "Dev"
        };
        PDFGenerator.CreatePersonPDF(person);
    }
}
Imports IronPdf
Public Class Person
	Public Property Id() As Integer
	Public Property FirstName() As String
	Public Property LastName() As String
End Class
Public Class PDFGenerator
	Public Shared Sub CreatePersonPDF(ByVal person As Person)
		Dim htmlContent = $"
        <html>
        <body>
            <h1>Person Information</h1>
            <p>ID: {person.Id}</p>
            <p>First Name: {person.FirstName}</p>
            <p>Last Name: {person.LastName}</p>
        </body>
        </html>"
		Dim renderer = New ChromePdfRenderer()
		Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
		pdf.SaveAs($"Person_{person.Id}.pdf")
	End Sub
End Class
Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim person As New Person With {
			.Id = 1,
			.FirstName = "Iron",
			.LastName = "Dev"
		}
		PDFGenerator.CreatePersonPDF(person)
	End Sub
End Class
VB   C#

結論

C# Init 關鍵字(對開發者的運作方式):圖 3 - IronPDF 授權頁面

總結來說,C# 的 init 關鍵字讓你可以在物件初始化時,創建不變物件並提供靈活性。 這是一種更乾淨且更安全的替代方案,用於私有設置訪問器,減少對構造函式樣板代碼的需求。 將 init 關鍵字與唯讀欄位、結構體及驗證邏輯結合使用,有助於構建強大且安全的資料結構,能夠在不犧牲可讀性或靈活性的情況下保持不變性。 IronPDF 提供一個免費試用,授權費用從 $749 起。 這可以讓您使用其全部功能,包括編輯、壓縮和保護PDF文件。

< 上一頁
FileStream C#(對開發人員的工作方式)
下一個 >
C# SemaphoreSlim(開發人員如何使用)

準備開始了嗎? 版本: 2024.12 剛剛發布

免費 NuGet 下載 總下載次數: 11,622,374 查看許可證 >