跳過到頁腳內容
.NET幫助

C# Record Vs Class(對於開發者的運行原理)

In the world of C#, two primary structures are utilized to model and encapsulate data: classes and records. 兩者都是引用類型,但在預期用途、行為和處理相等性方面存在顯著差異。 本指導將剖析這些差異,提供清晰的示例和實用用途,以幫助開發者選擇適合其需求的結構。 我們還將了解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
$vbLabelText   $csharpLabel

在上面的示例中,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)
$vbLabelText   $csharpLabel

在上面的示例中,記錄定義更加簡潔,減少了樣板代碼。 記錄自動支持非破壞性變更和基於值的比較。 具有相同值的兩個記錄實例被認為是相等的,這與值語義一致。

實用用途:何時使用記錄與類

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

記錄實現:

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

注意記錄實現的簡潔性和簡單性。 記錄自動生成構造函數、屬性和基於值的相等方法。

理解相等性:引用與值

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

具有相同屬性值的類的兩個實例不被認為是相等的,因為它們是內存中的不同對象。

值相等示例

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

具有相同屬性值的記錄的兩個實例按默認情況下被認為是相等的。

高級功能:記錄

記錄具有多個高級功能,以滿足對不可變數據結構和基於值的相等性的需求。 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" }
$vbLabelText   $csharpLabel

當處理不可變數據結構時,此功能非常有用,因為它提供了一種“不改變”實例而不更改原始數據的方法。

IronPDF 函式庫介紹

IronPDF 頁面

IronPDF 是一個供 .NET 開發人員使用的 PDF 庫,為在 .NET 應用程序中直接創建、編輯和管理 PDF 文檔提供了全面的解決方案。 它簡化了 PDF 生成過程,允許開發人員將 HTML 轉換為 PDF、CSS、JavaScript和圖像轉換為 PDF。 IronPDF 支持多種 .NET 框架和項目類型,包括 Web、桌面和控制台應用程序,可在多個操作系統(如 Windows、Linux 和 macOS)上使用。

除了創建 PDF,IronPDF 提供編輯 PDF、設置屬性和安全性、處理 PDF 表單和提取內容的功能。 它旨在滿足尋求可靠工具以在其 .NET 項目中集成 PDF 功能的開發人員的需求。

代碼示例

使用 IronPDF 在 C# 中創建 PDF 可以通過類和記錄來實現。 以下是生成簡單 PDF 文檔的兩種方法的示例。 在 C# 中類和記錄之間的主要區別在於它們的預期用途:類默認是可變的,設計用於傳統的面向對象編程,而記錄是不可變的,設計用於基於值的編程,使其成為數據建模的理想選擇。

使用類

在本示例中,我們將定義一個包含創建 PDF 方法的 PdfGenerator 類,該方法從給定的 HTML 字串創建 PDF。

using IronPdf;
using System;

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"; // Set your license key here

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

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"; // Set your license key here

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

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" ' Set your license key here

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

輸出:

類示例輸出的PDF

使用記錄

相比之下,C# 中的記錄在初始化後是不可變的。 這是您如何通過利用 with 表達式進行修改來使用記錄達到類似結果的示範,這本質上返回帶有所需更改的記錄的新實例。

using IronPdf;
using System;

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"; // Set your license key here

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

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"; // Set your license key here

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

'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" ' Set your license key here

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

輸出:

記錄示例輸出的PDF

這些示例示範了如何使用 IronPDF 在 C# 中生成 PDF 文件,無論是類還是記錄。 是否使用類或記錄的選擇取決於您的具體需求:如果需要在創建後修改對象,類可能更合適。 如果您處理的是一旦創建後保持不變的數據,或者喜好不可變性的語法簡潔和安全性,那麼記錄可能是更好的選擇。

結論

IronPDF 許可證頁面

總之,類提供傳統的面向對象特性,具有可變狀態和引用基於引用的相等性,而記錄則提供了一種現代方法來定義具有基於值相等的不可變數據結構。

使用類或記錄的選擇應由應用程序的具體需求引導,考慮諸如不可變性需求、數據結構的複雜性和喜好的相等性比較方法等因素。 了解 IronPDF 的免費試用版,適用於希望將 PDF 功能集成到其 .NET 應用程序的用戶,許可證從 $799 開始 。

常見問題解答

C# 類別和記錄的主要區別是什麼?

C# 類別和記錄都是用來建模和封裝數據的引用類型,但在處理相等性和不可變性方面有所不同。類別使用引用相等性,意味著兩個實例被視為相等是基於它們指向相同的記憶體位置。另一方面,記錄使用值相等性,考慮兩個實例的屬性具有相同的值時即為相等,並且默認設計為不可變。

如何決定在 C# 中使用類別還是記錄?

在 C# 中,使用類別還是記錄取決於您的具體需求。如果您需要可變實例,或希望在面向物件編程中封裝數據和行為,則使用類別。如果結構簡單、不可變,並且需要基於值的相等性(如在數據傳輸對象中),則選擇記錄。

IronPDF 庫如何支援 .NET 中的 PDF 生成?

IronPDF 是一個強大的 .NET PDF 庫,簡化了 PDF 文檔的創建、編輯和管理。它允許開發者將 HTML、CSS、JavaScript 和圖像轉換為 PDF,支持各種 .NET 框架和操作系統,是 .NET 開發者的必備工具。

我可以在 PDF 生成項目中同時使用 C# 類別和記錄嗎?

是的,在 PDF 生成項目中可以同時使用 C# 類別和記錄。選擇取決於您是否需要可變或不可變的數據結構。比如,IronPDF 可以與這兩種類型的結構順利協作來生成和操作 PDFs。

不可變性在 C# 記錄中發揮了什麼作用?

不可變性是 C# 記錄的核心特性。一旦創建,記錄的屬性就不能更改,符合基於值的相等語義。這一設計使記錄在需要數據一致性和完整性的情況下(如在數據傳輸對象中)成為理想選擇。

IronPDF 如何增強 .NET 應用程序的 PDF 功能?

IronPDF 通過提供將 HTML 轉換為 PDF、編輯 PDF 和管理文檔安全性的功能來增強 .NET 應用程序的 PDF 功能。它支持表單處理、內容提取,並無縫集成不同的 .NET 環境,從而簡化 PDF 文檔處理。

'with' 表達式在 C# 記錄中的作用是什麼?

'with' 表達式在 C# 記錄中用於非破壞性變更。它允許開發者通過複製現有的記錄實例並修改某些屬性來創建新的記錄實例,確保原始數據保持不變。

為什麼記錄被認為適合用於數據傳輸對象?

記錄被認為適合用於數據傳輸對象,因為它們提供了定義不可變結構的簡潔語法,具有基於值的相等性。這確保了數據完整性和具有相同值的實例被視為相等,這在數據傳輸中通常是期望的。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。