跳過到頁腳內容
.NET幫助

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

在 C# 的世界裡,有兩種主要的結構可用來建模和封裝資料: 類別 record。 這兩種工具都可作為參考類型,但在預期用途、行為和處理相等的方式上有顯著的差異。 本指南將剖析這些差異,提供清楚的範例和實際用途,協助開發人員選擇適合他們需求的結構。 我們也將學習 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# 中的 record 型別:不可變的資料結構

record 型別在 C# 中引入,是一種較新的新增功能,旨在簡化不可變資料結構的建立,提供傳統類別結構的強大替代方案。 與類別不同,record 型別提供基於值的相等語意,使其成為資料傳輸物件或只有很少或沒有行為的小型資料結構的理想選擇。

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

在上例中,record 定義更為簡潔,減少了模板程式碼。 record 自動支援非破壞性突變和基於值的比較。 具有相同值的兩個 record 實例被視為相等,與值的語義一致。

實際用途:何時使用 Record 與 Class

在 C# 中選擇類別和 record 型別或其他資料結構,取決於您建模資料的複雜性以及應用程式所需的行為。 類別是專為複雜的資料結構所設計,可容納行為(方法),並允許所需的可變實體。 另一方面,record 型別是簡單資料結構的完美範例,其設計具有不可變的特性和以值為基礎的相等性,是建立後保持不變的資料的理想選擇。

當您的資料結構需要封裝資料和行為,或是需要在資料建立後進行操作時,類別是最理想的選擇。 類的靈活性使類成為大多數傳統物件導向程式設計情境和建立複雜資料結構時的首選。

Records 在資料不變性極其重要的情況下,或是當您處理主要作為資料容器的簡單資料結構時,都會大放異彩。 這些工具內建以數值為基礎的平等性和簡潔的語法,使其成為資料傳輸物件或數值物件的絕佳選擇。

值類型和參考類型

瞭解 C# 中值類型與參考類型的差異至關重要。 類別是參考類型,意即變數持有對記憶體中實際資料的參考。 此特性導致預設的基於參考的平等比較。

record 型別(Records)雖然也是參照類型,但透過其內建的基於值的相等性來模擬值語意,使其在比較中的行為有點類似於值類型。

程式碼範例:實作類和 record 型別。

讓我們來實作一個類別和一個 record 型別,以突顯語法和行為上的差異。

類別實作:

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

record 型別實作:

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

請注意 record 型別實作的簡潔性。 此 record 會自動產生值基相等的構造器、屬性和方法。

瞭解等式:參照與值

C# 中類和 record 型別的核心差異確實在於它們如何處理相等性:

1.類別預設使用參考相等,意即兩個實體若指向相同的記憶體位置,則相等。

2.record 型別預設使用值相等,如果兩個實體的屬性具有相同的值,則視為相等。

參考等式範例 (類別)

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

預設情況下,具有相同屬性值的 record 的兩個實例會被視為相等。

進階功能:record 型別

record 型別具備多項進階功能,可滿足對不可變資料結構和基於值的平等性的需求。 with 表達式允許透過複製現有 record 來建立新的 record 實體,但會修改某些屬性,以展示非破壞性的變異。

使用 record 型別的非破壞性突變:

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 Framework 和專案類型,包括網頁、桌面和主控台應用程式,可跨 Windows、Linux 和 macOS 等多種作業系統。

除 PDF 創建外,IronPDF 還提供編輯 PDF、設定屬性和安全性、處理 PDF 表單以及提取內容等功能。 它旨在滿足那些正在尋找可靠工具將 PDF 功能整合到其 .NET 專案中的開發人員的需求。

程式碼範例

使用 IronPDF 在 C# 中創建 PDF 可以通過類別和 record 型別兩種方式實現。 以下是兩種方法產生簡單 PDF 文件的範例。 C# 中類和 record 型別的主要差異在於它們的預期用途:類預設是可變的,專為傳統的物件導向程式設計,而 record 型別是不可變的,專為以值為基礎的程式設計,因此非常適合資料建模。

使用類別

在這個範例中,我們將定義一個 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

使用 record 型別

相比之下,C# 中的 record 型別在初始化後是不可變的。 以下是如何使用 with 表達式對 record 進行修改,從而實現類似結果的方法,這本質上是傳回具有所需變更的 record 的新實例。

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

輸出:

 從 record 型別範例輸出 PDF

這些範例說明如何使用 IronPDF 以 C# 語言同時使用類別和 record 型別產生 PDF 檔案。 選擇使用類別或 record 型別取決於您的特定需求:如果您需要的物件在建立後會被修改,類別可能會比較適合。 如果您要處理的資料一旦建立就不應該改變,或者您欣賞語法上的簡單性及不可變性的安全性,record 型別可能是更好的選擇。

結論

IronPDF 授權頁面

總而言之,類別提供了傳統的物件導向功能,具有可變狀態和基於參照的相等性,而 record 型別則提供了現代的方法,以定義基於值的相等性的不可變資料結構。

在使用類別或 record 型別之間作出選擇時,應以您應用程式的特定需求為導向,並考慮各種因素,例如對不可變性的需求、資料結構的複雜性,以及優先使用的相等性比較方法。 探索 IronPDF 的免費試用版,該版本適用於希望將 PDF 功能整合到其 .NET 應用程式中的用戶,許可證價格從 $999 起。

常見問題解答

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Jacob Mellor, Team Iron 首席技術官
首席技術官

Jacob Mellor是Iron Software的首席技術官,也是開創C# PDF技術的前瞻性工程師。作為Iron Software核心代碼庫的原始開發者,他自公司成立以來就塑造了公司的產品架構,並與CEO Cameron Rimington將公司轉型為服務NASA、Tesla以及全球政府機構的50多人公司。

Jacob擁有曼徹斯特大學土木工程一級榮譽學士學位(1998年–2001年)。他於1999年在倫敦開立首家軟體公司,並於2005年建立了他的第一個.NET組件,專注於解決Microsoft生態系統中的複雜問題。

他的旗艦作品IronPDF和Iron Suite .NET程式庫全球已獲得超過3000萬次NuGet安裝,他的基礎代碼不斷在全球各地驅動開發者工具。擁有25年以上的商業經驗和41年的編碼專業知識,Jacob仍然專注於推動企業級C#、Java和Python PDF技術的創新,同時指導下一代技術領導者。

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我