C# 初始化關鍵字 (如何為開發人員運作)
C# 9.0中的init關鍵字引入了一種定義類屬性的新的方式,用於建立不可變的物件。 在早期版本的C#中,屬性通常使用get和set存取器來讀取和寫入物件欄位。 然而,使用init,您可以在物件初始化期間使屬性可寫,之後將其設為唯讀。
本教程將通過實際範例和場景使用IronPDF程式庫來探索使用C# init關鍵字。 您也會了解傳統屬性設置器(set)和新的init-only設置器之間的重要區別。
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.

在這個例子中,LastName被標記為init-only屬性。 這意味著它們僅能在物件初始化期間被賦值。 物件建立後,嘗試更改這些值會導致編譯時錯誤。
為什麼使用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"
}
使用Init-Only屬性進行物件初始化
使用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
這建立了一個簡單且不可變的Point型別的物件。 注意,Y的值是在初始化時設置的,之後無法修改。
將init與構造函式混合使用
盡管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
您可以將構造函式和init屬性一起使用。 這種方法提供了更多的靈活性,同時在物件構建後仍然保持不可變性。
Init相對於Private Set的優勢
以前,開發者使用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
儘管這種方法有效,但它需要構造函式樣板程式碼來初始化屬性。 此外,這允許類本身在以後修改屬性,對於不可變物件而言並不總是理想的。 init關鍵字消除了這個問題,因為它只允許在物件建立時初始化,並在以後阻止任何修改。
使用唯讀欄位和Init存取器進行初始化
init關鍵字可以在物件建立期間初始化欄位或屬性,同時在之後保持不可變性。 雖然唯讀欄位提供不可變性,但init存取器為屬性提供了類似的功能。 這是您可以以兩種方式處理不可變性的方式:使用唯讀欄位和init屬性。
使用構造函式與唯讀欄位
在本例中,我們對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
使用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
簡介IronPDF

IronPDF是一個為C#開發者設計的強大的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
結論

總之,C# init關鍵字允許您在提供物件初始化靈活性的同時建立不可變物件。 它是一種比私有set存取器更清晰和更安全的替代方案,減少了構造函式樣板程式碼的需求。 將init關鍵字與唯讀欄位、結構體和驗證邏輯結合使用有助於構建健全且安全的資料結構,保持不可變性而不犧牲可讀性或靈活性。 IronPDF提供免費試用,授權價格從$999開始。 這讓您可以使用其全部功能,包括編輯、壓縮和保護PDF。
常見問題
如何在C#中將HTML轉換成PDF?
您可以使用IronPDF的RenderHtmlAsPdf方法將HTML字串轉換成PDF。您也可以使用RenderHtmlFileAsPdf將HTML文件轉換為PDF。
C#中初始化關鍵字的目的是什麼?
初始化關鍵字允許您定義只能在物件初始化期間設置的屬性,確保之後的不可變性。這個功能對於建立一旦建立就不應更改的物件特別有用。
初始化關鍵字如何增強C#中的物件不可變性?
初始化關鍵字使屬性僅能在物件的初始化階段設定,之後阻止任何更改。這保證了物件一旦被建立就保持不可變性。
可以用於PDF生成程式庫的初始化屬性嗎?
是的,初始化屬性可以與像IronPDF這樣的程式庫一起使用,從不可變的物件生成PDF,確保用於PDF的資料在整個過程中保持一致。
使用初始化關鍵字比傳統設置器有何優勢?
使用初始化關鍵字比傳統設置器推動了不可變性,減少了冗長的構造函式程式碼,而且確保了物件屬性在初始化後不能被修改。
如何在C#中將PDF生成與不可變屬性結合?
您可以用初始化屬性建立不可變的物件,並將這些物件傳遞給IronPDF,它可以利用這些資料生成一致且可靠的PDF文件。
初始化關鍵字在建立現代C#應用程式中扮演什麼角色?
初始化關鍵字在建立現代C#應用程式中扮演著至關重要的角色,讓開發者能夠使用簡潔的語法定義不可變的物件,增強程式碼安全性,並減少錯誤。
如何在C#項目中安裝PDF生成程式庫?
您可以使用NuGet Package Manager在C#項目中安裝像IronPDF這樣的程式庫,命令為:Install-Package IronPdf。
為何不可變性在應用程式開發中很重要?
不可變性很重要,因為它確保了您的應用程式中資料的整體性和一致性,使得維護更為簡便,並降低了錯誤的可能性。
哪些實用範例說明了初始化關鍵字的使用?
一個實用範例是使用初始化關鍵字來定義一個類,其中屬性能僅在初始化期間設置,確保建立的物件保持不變。這在資料一致性至關重要的情境中特別有用。




