.NET 帮助

C#记录与类(开发人员如何使用)

发布 2024年八月11日
分享:

在 C# 的世界里,有两种主要结构被用来对数据进行建模和封装:记录. 这两种工具都可作为参考类型,但在预期用途、行为和处理平等性的方式上有很大不同。 本指南将剖析这些差异,提供清晰的示例和实际用途,帮助开发人员根据自己的需求选择合适的结构。 我们还将了解IronPDF 库.

C# 中的类:基础知识

类一直是 C# 中面向对象编程的基石,旨在封装数据和行为。 它们是引用类型,这意味着具有相同值的两个类实例被视为两个独立的对象。 在比较两个类实例时,这种区别至关重要; 默认的比较是基于参考,而不是基于价值。

public class Person
{
    public int Id { get; set; }
    public string FullName { get; set; }
}
public class Person
{
    public int Id { get; set; }
    public string FullName { get; set; }
}
Public Class Person
	Public Property Id() As Integer
	Public Property FullName() As String
End Class
VB   C#

在上面的例子中,Person 是一个具有 IdFullName 属性的类。 即使两个Person实例的IdFullName值完全相同,默认情况下它们也不会被视为相同,因为它们在内存中是两个不同的引用。

C# 中的记录:不可变数据结构

记录类型在 C# 中引入,是一种较新的新增类型,旨在简化不可变数据结构的创建,为传统的类结构提供了一个强大的替代选择。 与类不同,记录提供基于值的等价语义,是数据传输对象或行为很少或没有行为的小型数据结构的理想选择。

public record Person(int Id, string FullName);
public record Person(int Id, string FullName);
'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record Person(int Id, string FullName)
VB   C#

在上例中,记录定义更加简洁,减少了模板代码。 记录自动支持无损突变和基于值的比较。 具有相同值的两个记录实例被视为相等,这与值的语义一致。

实际用途:何时使用记录与类

在类和记录或 C# 中的其他数据结构之间做出选择,取决于您要建模的数据的复杂性和您的应用程序所需的行为。 类专为复杂的数据结构而设计,可容纳以下行为(方法)并允许根据需要使用可变实例。 另一方面,记录是简单数据结构的完美范例,具有不可变的特性和基于值的平等性,是创建后保持不变的数据的理想选择。

当您的数据结构需要封装数据和行为,或者需要在创建数据后对其进行操作时,类是理想的选择。 类的灵活性使其成为大多数传统面向对象编程场景和创建复杂数据结构时的首选。

记录在数据不变性至关重要的情况下或在处理主要作为数据容器的简单数据结构时大放异彩。 它们内置的基于值的平等性和简洁的语法使其成为数据传输对象或值对象的绝佳选择。

值类型和引用类型

了解 C# 中值类型和引用类型的区别至关重要。 类是引用类型,这意味着变量持有对内存中实际数据的引用。 这一特点导致了默认的基于参考文献的平等比较。

记录虽然也是引用类型,但通过其内置的基于值的相等性模拟了值语义,使其在比较中的行为有点像值类型。

代码示例:实现类和记录

让我们实现一个类和一条记录,以突出语法和行为上的差异。

类实现:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Product(int id, string name)
    {
        Id = id;
        Name = name;
    }
}
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Product(int id, string name)
    {
        Id = id;
        Name = name;
    }
}
Public Class Product
	Public Property Id() As Integer
	Public Property Name() As String

	Public Sub New(ByVal id As Integer, ByVal name As String)
		Me.Id = id
		Me.Name = name
	End Sub
End Class
VB   C#

记录实施:

public record Product(int Id, string Name);
public record Product(int Id, string Name);
'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record Product(int Id, string Name)
VB   C#

请注意记录实现的简洁性。 该记录会自动生成基于值的相等的构造函数、属性和方法。

理解平等:引用与值

C# 中类和记录类型的核心区别确实在于它们如何处理相等性:

  1. 类默认使用引用相等,这意味着如果两个实例指向相同的内存位置,它们就是相等的。

  2. 记录默认使用值相等,如果两个实例的属性具有相同的值,则认为它们相等。

    参考平等示例(班级)

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

var classInstance1 = new Person { Id = 1, Name = "Iron Software" };
var classInstance2 = new Person { Id = 1, Name = "Iron Software" };
Console.WriteLine(classInstance1 == classInstance2); // Outputs: False
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

var classInstance1 = new Person { Id = 1, Name = "Iron Software" };
var classInstance2 = new Person { Id = 1, Name = "Iron Software" };
Console.WriteLine(classInstance1 == classInstance2); // Outputs: False
Public Class Person
	Public Property Id() As Integer
	Public Property Name() As String
End Class

Private classInstance1 = New Person With {
	.Id = 1,
	.Name = "Iron Software"
}
Private classInstance2 = New Person With {
	.Id = 1,
	.Name = "Iron Software"
}
Console.WriteLine(classInstance1 = classInstance2) ' Outputs: False
VB   C#

具有相同属性值的两个类实例不被视为等同,因为它们在内存中是不同的对象。

数值相等示例

public record Person(int Id, string Name);

var recordInstance1 = new Person(1, "Iron Software");
var recordInstance2 = new Person(1, "Iron Software");
Console.WriteLine(recordInstance1 == recordInstance2); // Outputs: True
public record Person(int Id, string Name);

var recordInstance1 = new Person(1, "Iron Software");
var recordInstance2 = new Person(1, "Iron Software");
Console.WriteLine(recordInstance1 == recordInstance2); // Outputs: True
'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record Person(int Id, string Name)

Private recordInstance1 = New Person(1, "Iron Software")
Private recordInstance2 = New Person(1, "Iron Software")
Console.WriteLine(recordInstance1 = recordInstance2) ' Outputs: True
VB   C#

默认情况下,具有相同属性值的两个记录实例被视为相等。

高级功能:记录

记录具有多种高级功能,可满足对不可变数据结构和基于值的平等性的需求。 with表达式允许通过复制现有记录来创建新的记录实例,但要修改某些属性,从而展示无损突变。

使用记录的无损突变:

var originalRecord = new Person(1, "Doe");
var modifiedRecord = originalRecord with { Name = "Iron Developer" };
var originalRecord = new Person(1, "Doe");
var modifiedRecord = originalRecord with { Name = "Iron Developer" };
Dim originalRecord = New Person(1, "Doe")
'INSTANT VB TODO TASK: C# 'with expressions' are not converted by Instant VB:
'var modifiedRecord = originalRecord with { Name = "Iron Developer" }
VB   C#

这一功能在处理不可变数据结构时非常方便,因为它提供了一种 "修改 "实例而不改变原始数据的方法。

IronPDF 库简介

IronPDF 网页

IronPDFPDF 是为 .NET 开发人员提供的 PDF 库,它为直接在 .NET 应用程序中创建、编辑和管理 PDF 文档提供了全面的解决方案。 它简化了 PDF 生成过程,允许开发人员将 HTML 转换为 PDF将 CSS、JavaScript 和图像翻译成 PDF。 IronPdf for .NET 支持各种 .NET Framework 和项目类型,包括 Web、桌面和控制台应用程序,可跨 Windows、Linux 和 macOS 等多个操作系统。

除创建 PDF 外,IronPDF 还提供编辑 PDF、设置属性和安全性、处理 PDF 表单以及提取内容等功能。 它旨在满足开发人员的需求,使他们能够寻找可靠的工具,将 PDF 功能集成到他们的 .NET 项目中。

代码示例

使用 IronPdf 在 C# 中创建 PDF 可以通过类和记录两种方式实现。 以下是两种方法生成简单 PDF 文档的示例。 C# 中类和记录的主要区别在于它们的预期用途:类默认是可变的,专为传统的面向对象编程而设计,而记录是不可变的,专为基于值的编程而设计,是数据建模的理想选择。

使用类

在本例中,我们将定义一个 PdfGenerator 类,该类包含一个从给定 HTML 字符串创建 PDF 的方法。

using IronPdf;

public class PdfGenerator
{
    public string HtmlContent { get; set; }

    public PdfGenerator(string htmlContent)
    {
        HtmlContent = htmlContent;
    }

    public void GeneratePdf(string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(HtmlContent);
        pdfDocument.SaveAs(filePath);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        License.LicenseKey = "License-Key";

        var generator = new PdfGenerator("<h1>Hello, World from Class!</h1>");
        generator.GeneratePdf("ClassExample.pdf");
    }
}
using IronPdf;

public class PdfGenerator
{
    public string HtmlContent { get; set; }

    public PdfGenerator(string htmlContent)
    {
        HtmlContent = htmlContent;
    }

    public void GeneratePdf(string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(HtmlContent);
        pdfDocument.SaveAs(filePath);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        License.LicenseKey = "License-Key";

        var generator = new PdfGenerator("<h1>Hello, World from Class!</h1>");
        generator.GeneratePdf("ClassExample.pdf");
    }
}
Imports IronPdf

Public Class PdfGenerator
	Public Property HtmlContent() As String

	Public Sub New(ByVal htmlContent As String)
		Me.HtmlContent = htmlContent
	End Sub

	Public Sub GeneratePdf(ByVal filePath As String)
		Dim renderer = New ChromePdfRenderer()
		Dim pdfDocument = renderer.RenderHtmlAsPdf(HtmlContent)
		pdfDocument.SaveAs(filePath)
	End Sub
End Class

Friend Class Program
	Public Shared Sub Main(ByVal args() As String)
		License.LicenseKey = "License-Key"

		Dim generator = New PdfGenerator("<h1>Hello, World from Class!</h1>")
		generator.GeneratePdf("ClassExample.pdf")
	End Sub
End Class
VB   C#

输出:

课堂示例输出的PDF

使用记录

相比之下,C# 中的记录在初始化后是不可变的。 以下是您如何利用 with-expression 来修改记录,从而获得类似的结果,with-expression 本质上是返回一个带有所需更改的新记录实例。

using IronPdf;

public record PdfGeneratorRecord(string HtmlContent)
{
    public void GeneratePdf(string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(this.HtmlContent);
        pdfDocument.SaveAs(filePath);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        License.LicenseKey = "License-Key";

        var recordGenerator = new PdfGeneratorRecord("<h1>Hello, World from Record!</h1>");
        recordGenerator.GeneratePdf("RecordExample.pdf");
    }
}
using IronPdf;

public record PdfGeneratorRecord(string HtmlContent)
{
    public void GeneratePdf(string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(this.HtmlContent);
        pdfDocument.SaveAs(filePath);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        License.LicenseKey = "License-Key";

        var recordGenerator = new PdfGeneratorRecord("<h1>Hello, World from Record!</h1>");
        recordGenerator.GeneratePdf("RecordExample.pdf");
    }
}
Imports IronPdf

'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record PdfGeneratorRecord(string HtmlContent)
'{
'	public void GeneratePdf(string filePath)
'	{
'		var renderer = New ChromePdfRenderer();
'		var pdfDocument = renderer.RenderHtmlAsPdf(Me.HtmlContent);
'		pdfDocument.SaveAs(filePath);
'	}
'}

Friend Class Program
	Public Shared Sub Main(ByVal args() As String)
		License.LicenseKey = "License-Key"

		Dim recordGenerator = New PdfGeneratorRecord("<h1>Hello, World from Record!</h1>")
		recordGenerator.GeneratePdf("RecordExample.pdf")
	End Sub
End Class
VB   C#

输出:

从记录示例输出的PDF

这些示例说明了如何使用 IronPdf 通过 C# 中的类和记录生成 PDF 文件。 选择使用类还是记录取决于您的具体需求:如果您需要的对象在创建后会被修改,那么使用类可能更合适。 如果您要处理的数据一旦创建就不应该改变,或者您欣赏语法的简洁性和不变性的安全性,那么记录可能是更好的选择。

结论

IronPDF许可页面

总之,类提供了传统的面向对象功能,具有可变状态和基于引用的等价性,而记录则提供了一种现代方法来定义不可变的数据结构,具有基于值的等价性。

在选择使用类还是记录时,应根据应用程序的具体要求,考虑对不变性的需求、数据结构的复杂性以及首选的等价比较方法等因素。 了解 IronPDF 免费试用版对于那些希望将 PDF 功能集成到其 .NET 应用程序中的用户,许可证价格从 749 美元起。

< 前一页
C# 休眠 (开发人员如何使用)
下一步 >
MySqlclient C#(开发人员使用指南)

准备开始了吗? 版本: 2024.12 刚刚发布

免费NuGet下载 总下载量: 11,781,565 查看许可证 >