跳至頁尾內容
.NET幫助

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

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

注意記錄實作的簡潔和簡單。 記錄自動生成建構子、屬性和方法以實現基於值的等同性。

了解等同性:參考 vs. 值

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程式庫,提供建立、編輯和管理PDF文件的全面解決方案,直接在.NET應用程式中運行。 它通過允許開發人員將HTML轉換為PDF、CSS、JavaScript和圖片轉換為PDF,大大簡化了PDF生成過程。 IronPDF支持多種.NET框架和專案型別,包括Web、桌面和控制台應用程式,適用於Windows、Linux和macOS等多個作業系統。

除了PDF建立之外,IronPDF還提供編輯PDF、設置屬性和安全性、處理PDF表單以及提取內容的功能。 該產品旨在滿足那些尋求可靠工具將PDF功能整合到其.NET專案中的開發者需求。

程式程式碼範例

使用IronPDF在C#中建立PDF可以通過類別和記錄來實現。 下面是兩種方法生成簡單PDF文件的範例。 C#中類別和記錄之間的主要區別在於它們的預期用途:類別預設為可變,專為傳統物件導向編程設計,而記錄不可變且專為基於值設計,使其成為資料建模的理想選擇。

使用類別

在這個範例中,我們將定義一個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的免費試用,適合那些希望在其.NET應用程式中整合PDF功能的人,授權起價為$999。

常見問題

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

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

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

在 C# 中選擇使用類別或記錄取決於您的具體需求。如果您需要可變實例或想要封裝物件導向程式設計中典型的資料和行為,請使用類別。如果您的結構簡單、不可變,並且需要基於值的等同性,請使用記錄,例如資料傳輸物件。

IronPDF 程式庫如何支援在 .NET 中生成 PDF?

IronPDF 是一個強大的 .NET PDF 程式庫,簡化了 PDF 文件的建立、編輯和管理。它允許開發者將 HTML、CSS、JavaScript 和圖像轉換為 PDF,支援各種 .NET Framework和操作系統,使其成為 .NET 開發人員不可或缺的工具。

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

是的,您可以在 PDF 生成專案中使用 C# 類別和記錄。選擇取決於您是否需要可變或不可變的資料結構來進行邏輯運算。例如,IronPDF 可以無縫地與任一結構一起工作來生成和操作 PDF。

不可變性在 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核心程式碼庫的原開發者,他從創立以來就一直在塑造公司的產品架構,與首席執行官Cameron Rimington一起將公司轉變為服務於NASA、特斯拉和全球政府公司的50多名人員的公司。

Jacob擁有曼徹斯特大學的土木工程一等榮譽學士學位(BEng),於1998-2001年之間獲得。在1999年於倫敦創辦他的第一家軟體公司並於2005年建立了他的第一批.NET元組件後,他專注於解決Microsoft生態系統中的複雜問題。

他的旗艦IronPDF和Iron Suite .NET程式庫在全球獲得了超過3000萬次NuGet安裝依據,他的基礎程式碼基繼續支援著世界各地開發者使用的工具。擁有25年的商業經驗和41年的程式設計專業知識,他仍專注於推動企業級C#、Java和Python PDF技術的創新,同時指導下一代技術領導者。

Iron 支援團隊

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