.NET 帮助

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

Chipego
奇佩戈-卡琳达
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.

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"
};

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

使用 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

这将创建一个简单、不可变的 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;
    }
}

您可以同时使用构造函数和 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;
    }
}

虽然这种方法可行,但需要构造函数模板代码来初始化属性。 此外,它还允许类本身稍后修改属性,这对于不可变对象来说并不总是理想的。 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;
    }
}

使用 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; }
}

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

以下是代码示例:

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);
    }
}

结论

C# Init 关键字(如何为开发人员工作):图 3 - IronPDF 许可页面

总之,C# init 关键字允许您创建不可变对象,同时在对象初始化过程中提供灵活性。 它是私有集访问器的一个更简洁、更安全的替代方案,减少了对构造器模板代码的需求。 将 init 关键字与只读字段、结构体和验证逻辑相结合,可以帮助您构建稳健、安全的数据结构,在保持不变性的同时不牺牲可读性或灵活性。 IronPDF 提供一个免费试用,并且许可证起价为 $749。 您可以使用它的全部功能,包括编辑、压缩和保护 PDF。

Chipego
软件工程师
Chipego 拥有出色的倾听技巧,这帮助他理解客户问题并提供智能解决方案。他在 2023 年加入 Iron Software 团队,此前他获得了信息技术学士学位。IronPDF 和 IronOCR 是 Chipego 主要专注的两个产品,但他对所有产品的了解每天都在增长,因为他不断找到支持客户的新方法。他喜欢 Iron Software 的合作氛围,公司各地的团队成员贡献他们丰富的经验,以提供有效的创新解决方案。当 Chipego 离开办公桌时,你经常可以发现他在看书或踢足球。
< 前一页
FileStream C#(面向开发人员的工作原理)
下一步 >
C# Semaphoreslim(如何为开发人员工作)