跳過到頁腳內容
.NET幫助

C# 初始化關鍵字 (如何為開發人員運作)

C# 9.0 中的init關鍵字引入了一種新的定義類屬性的方法,用於創建不可變的物件。 在 C# 的早期版本中,properties 通常與 get 和 set 存取器一起使用,以從物件欄位讀取或寫入物件欄位。 但是,使用 init,您可以僅在物件初始化時使屬性可寫,之後使其成為唯讀。

本教學將以 IronPDF 函式庫的實用範例和情境,探索如何使用 C# init 關鍵字。 您也將學習到傳統的屬性設定器 (set) 與新的僅限於 init 的設定器之間的關鍵差異。

Init 關鍵字的基本範例

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

public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}

var person = new Person
{
    FirstName = "Iron",
    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",
    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",
	.LastName = "Dev"
}

' person.FirstName = "Jane";  // This will give a compile-time error.
$vbLabelText   $csharpLabel

C# Init Keyword (How It Works For Developers):圖 1 - IDE 由於屬性被標記為 init-only 而產生錯誤

在這個例子中,FirstNameLastName 被標記為僅初始化屬性。 這表示它們只能在物件初始化時指定。 物件建立後,嘗試變更數值會導致編譯時錯誤。

為什麼要使用 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"
}
$vbLabelText   $csharpLabel

使用僅初始化屬性進行物件初始化

使用 init 可與物件初始化器無縫配合。 您可以在建立物件時直接定義所需的屬性,而不必仰賴建構器來設定值。

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
$vbLabelText   $csharpLabel

這將建立一個類型為 Point 的簡單、不可變物件。 請注意,XY 的值在初始化時設置,以後無法修改。

將 init 與 Constructors 混合。

雖然 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
$vbLabelText   $csharpLabel

您可以同時使用構建器和 init 屬性。 此方法提供更多的彈性,同時在物件建構後仍能強制執行不可變性。

Init Over Private Set 的優點

以前,開發人員使用私有的 set accessor 來限制在類別之外的屬性修改。

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
$vbLabelText   $csharpLabel

儘管這種方法可行,但需要使用構建器的模板程式碼來初始化屬性。 此外,它允許類本身稍後修改屬性,這對不可變的物件來說並不總是理想的做法。 init 關鍵字消除了這個問題,因為它只允許在物件建立時進行初始化,之後的任何修改都會被阻擋。

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

init 關鍵字可以在建立物件時初始化欄位或屬性,而之後這些欄位或屬性仍保持不變。 唯讀欄位提供不變性,而 init 存取器則為屬性提供類似的功能。 這裡有兩種處理不可變性的方法:使用唯讀欄位和 init 屬性。

使用構成器的唯讀欄位

在這個例子中,我們使用唯讀欄位 firstNamelastName,這些欄位是在物件建構期間設定的。 這些欄位只能在構建器中指定一次,之後不能修改:

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
$vbLabelText   $csharpLabel

使用 Init Accessor 進行初始化

另外,我們也可以使用 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
$vbLabelText   $csharpLabel

IronPDF 簡介

C# Init Keyword (How It Works For Developers):圖 2 - IronPDF:C# PDF Library

IronPDF是專為 C# 開發人員設計的功能強大的 PDF 產生和處理函式庫。 它簡化了使用 PDF的工作,將 HTML、CSS、圖片和其他內容轉換成 PDF 文件。 IronPDF 具備像素完美渲染、跨平台支援以及輕鬆整合至 .NET 專案等功能,是需要快速建立高品質 PDF 的開發人員的理想選擇。 您可以在 .NET Core、Framework 和 Standard 上使用它,而且它支援多種平台,包括 Windows、Linux 和 macOS。

案例:使用 IronPDF 與 C# Init 關鍵字。

若要在 C# 專案中建立不可變的物件,同時產生 PDF,您可以結合 init 關鍵字與 IronPDF。 init 關鍵字可確保物件初始化後的完整性,而 IronPDF 則會根據該不可變模型處理資料並產生 PDF。

確保 IronPDF 在您的專案中被正確引用。 您可以透過 NuGet 安裝:

Install-Package IronPdf

以下是程式碼範例:

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
$vbLabelText   $csharpLabel

結論

C# Init Keyword (How It Works For Developers):圖 3 - IronPDF 授權頁面

總而言之,C# init 關鍵字允許您建立不可變的物件,同時在物件初始化時提供彈性。 它是私有集存取器的一個更乾淨、更安全的替代方案,減少了對構建器模板程式碼的需求。 將 init 關鍵字與唯讀欄位、結構及驗證邏輯相結合,可協助您建立強大且安全的資料結構,在不犧牲可讀性或彈性的情況下,保留不變性。 IronPDF 提供免費試用,許可證起價為$999 。 這可讓您使用其完整功能,包括編輯、壓縮和保護 PDF。

常見問題解答

怎樣在 C# 中將 HTML 轉換為 PDF?

您可以使用 IronPDF 的 RenderHtmlAsPdf 方法將 HTML 字串轉換為 PDF。您還可以使用 RenderHtmlFileAsPdf 將 HTML 文件轉換為 PDF。

C# 中 init 關鍵字的目的是什麼?

init 關鍵字允許您定義只能在物件初始化期間設定的屬性,從而確保其後的不變性。這項功能對於建立應保持不變的物件非常有用。

init 關鍵字如何增強 C# 中物件的不可變性?

init 關鍵字可使屬性僅在物件的初始化階段設置,從而防止其後任何更改。這確保了物件在建立後保持不可變性。

init 屬性可以用於 PDF 生成庫嗎?

是的,init 屬性可以與像 IronPDF 這樣的庫一起使用,從不可變的物體生成 PDF,以確保 PDF 中所用資料在整個過程中保持一致。

使用 init 關鍵字比傳統設置器有何優勢?

相較於傳統設置器,使用 init 關鍵字可以提升不可變性,減少冗長的建構函式程式碼,並確保在初始化後物件屬性無法修改。

如何將 PDF 生成與 C# 中的不可變屬性整合?

您可以使用 init 屬性建立不可變物件並將其傳遞給 IronPDF,這可以利用資料生成一致且可靠的 PDF 文件。

init 關鍵字在建立現代 C# 應用程式中扮演了什麼角色?

init 關鍵字在建立現代 C# 應用程式中非常重要,因為它允許開發者以簡潔的語法定義不可變物件,提高程式碼的安全性並減少錯誤。

如何在 C# 專案中安裝 PDF 生成庫?

您可以使用 NuGet Package Manager 利用以下命令在 C# 專案中安裝像 IronPDF 這樣的庫:Install-Package IronPDF

為什麼不可變性在應用程式開發中很重要?

不可變性很重要,因為它確保了應用程式中的資料完整性與一致性,使得維護更容易且降低了錯誤發生的可能性。

有哪些實用例子展示 init 關鍵字的使用?

一個實例是使用 init 關鍵字定義一個類別,其屬性只能在初始化時設置,確保所建立的物件保持不變。這在資料一致性至關重要的情況下特別有用。

Jacob Mellor, Team Iron 首席技術官
首席技術官

Jacob Mellor是Iron Software的首席技術官,也是開創C# PDF技術的前瞻性工程師。作為Iron Software核心代碼庫的原始開發者,他自公司成立以來就塑造了公司的產品架構,並與CEO Cameron Rimington將公司轉型為服務NASA、Tesla以及全球政府機構的50多人公司。

Jacob擁有曼徹斯特大學土木工程一級榮譽學士學位(1998年–2001年)。他於1999年在倫敦開立首家軟體公司,並於2005年建立了他的第一個.NET組件,專注於解決Microsoft生態系統中的複雜問題。

他的旗艦作品IronPDF和Iron Suite .NET程式庫全球已獲得超過3000萬次NuGet安裝,他的基礎代碼不斷在全球各地驅動開發者工具。擁有25年以上的商業經驗和41年的編碼專業知識,Jacob仍然專注於推動企業級C#、Java和Python PDF技術的創新,同時指導下一代技術領導者。

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我