.NET 帮助

C# Init 关键字(如何为开发人员工作)

发布 2024年十月24日
分享:

"(《世界人权宣言》)启动关键字在 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#

使用仅初始化属性进行对象初始化

使用 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
VB   C#

这将创建一个简单、不可变的 Point 类型对象。 请注意,X 和 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
VB   C#

您可以同时使用构造函数和 init 属性。 这种方法具有更大的灵活性,同时在构建对象后仍能确保不变性。

Init 相对于私有集的优势

以前,开发人员使用私有设置访问器来限制类外的属性修改。

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 访问器处理初始化

init 关键字可以在创建对象时初始化字段或属性,并在创建对象后保持不变。 只读字段提供了不可变性,而 init 访问器为属性提供了类似的功能。 下面介绍两种处理不变性的方法:使用只读字段和 init 属性。

使用构造函数的只读字段

在本示例中,我们使用只读字段来表示 name 和 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是一个功能强大的 PDF 生成和操作库,专为 C# 开发人员设计。 它简化了使用通过转换 HTML 编写 PDF将 CSS、图像和其他内容翻译成 PDF 文档。 IronPDF 具有像素级完美渲染、跨平台支持和易于集成到 .NET 项目等特点,是需要快速创建高质量 PDF 的开发人员的理想选择。 您可以在 .NET Core、Framework 和 Standard 中使用它,它支持多种平台,包括 Windows、Linux 和 macOS。

案例:使用 IronPdf 与 C# Init 关键字

要在生成 PDF 的同时在 C# 项目中创建不可变对象,可以将 init 关键字与 IronPDF 结合使用。 init 关键字确保了对象初始化后的完整性,而 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,781,565 查看许可证 >