.NET 幫助

C# 結構與類別(開發人員的運作方式)

在 C# 中,結構體和類都是組織和存儲數據的基本構件,但它們具有不同的特性,使其適合於不同的場景。 理解C# 結構體和類別之間的差異,對於在設計 C# 應用程式時做出明智的決定至關重要。

在本文中,我們將探討結構體和類別的主要區別,討論它們的使用情境、記憶體管理以及效能影響。 此外,我們將討論如何使用結構和類別來搭配 IronPDF for C# 創建 PDF 文件。

結構體和類別概述

1.1. 類別(參考類型)

參考類型:在 C# 中,類別是位於堆中的參考類型,這意味著當建立類別的實例時,物件的參考將儲存在記憶體中。

堆分配:類別實例在堆內存分配上分配記憶體,提供大小上的靈活性,並允許物件在不同的程式碼部分之間共享。

預設建構子:類別可以有一個預設建構子,如果未明確定義,系統會自動提供。

繼承:類別支持繼承,允許創建具有共同特徵的衍生類別。

using System;
// Define a class
public class MyClass
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyClass(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyClass: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the class
        MyClass myClassInstance = new MyClass(10);
        // Access field and call method
        myClassInstance.Display();
        // Classes are reference types, so myClassInstance refers to the same object in memory
        MyClass anotherInstance = myClassInstance;
        anotherInstance.MyField = 20;
        // Both instances refer to the same object, so the change is reflected in both
        myClassInstance.Display();
        anotherInstance.Display();
    }
}
using System;
// Define a class
public class MyClass
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyClass(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyClass: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the class
        MyClass myClassInstance = new MyClass(10);
        // Access field and call method
        myClassInstance.Display();
        // Classes are reference types, so myClassInstance refers to the same object in memory
        MyClass anotherInstance = myClassInstance;
        anotherInstance.MyField = 20;
        // Both instances refer to the same object, so the change is reflected in both
        myClassInstance.Display();
        anotherInstance.Display();
    }
}
Imports System
' Define a class
Public Class [MyClass]
	' Fields (data members)
	Public MyField As Integer
	' Constructor
	Public Sub New(ByVal value As Integer)
		MyField = value
	End Sub
	' Method
	Public Sub Display()
		Console.WriteLine($"Value in MyClass: {MyField}")
	End Sub
End Class
Friend Class Program
	Shared Sub Main()
		' Create an instance of the class
		Dim myClassInstance As [MyClass] = New [MyClass](10)
		' Access field and call method
		myClassInstance.Display()
		' Classes are reference types, so myClassInstance refers to the same object in memory
		Dim anotherInstance As [MyClass] = myClassInstance
		anotherInstance.MyField = 20
		' Both instances refer to the same object, so the change is reflected in both
		myClassInstance.Display()
		anotherInstance.Display()
	End Sub
End Class
$vbLabelText   $csharpLabel

C# 結構與類別(開發人員的運作方式):圖 1 - 來自先前程式碼的控制台輸出

1.2. 結構 (值類型)

值類型: 結構體是值類型,這意味著實際數據存儲在變量聲明的地方,而不是像原始類型那樣在內存的單獨位置中。這也意味著結構體不能作為值類型被賦予空值,除非使用 Nullable<> 標籤將其設為可空類型。

堆疊配置: 結構實例在堆疊上分配記憶體,這樣的分配和釋放速度更快,但在大小和作用範圍上有一定的限制。

無預設建構函式:結構體沒有預設建構函式,除非明確定義。 每個字段必須在實例化期間初始化。

無繼承: 結構體不支援繼承。 它們主要用於輕量級數據結構。

using System;
// Define a struct
public struct MyStruct
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyStruct(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyStruct: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the struct
        MyStruct myStructInstance = new MyStruct(10);
        // Access field and call method
        myStructInstance.Display();
        // Structs are value types, so myStructInstance is a copy
        MyStruct anotherInstance = myStructInstance;
        anotherInstance.MyField = 20;
        // Changes to anotherInstance do not affect myStructInstance
        myStructInstance.Display();
        anotherInstance.Display();
    }
}
using System;
// Define a struct
public struct MyStruct
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyStruct(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyStruct: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the struct
        MyStruct myStructInstance = new MyStruct(10);
        // Access field and call method
        myStructInstance.Display();
        // Structs are value types, so myStructInstance is a copy
        MyStruct anotherInstance = myStructInstance;
        anotherInstance.MyField = 20;
        // Changes to anotherInstance do not affect myStructInstance
        myStructInstance.Display();
        anotherInstance.Display();
    }
}
Imports System
' Define a struct
Public Structure MyStruct
	' Fields (data members)
	Public MyField As Integer
	' Constructor
	Public Sub New(ByVal value As Integer)
		MyField = value
	End Sub
	' Method
	Public Sub Display()
		Console.WriteLine($"Value in MyStruct: {MyField}")
	End Sub
End Structure
Friend Class Program
	Shared Sub Main()
		' Create an instance of the struct
		Dim myStructInstance As New MyStruct(10)
		' Access field and call method
		myStructInstance.Display()
		' Structs are value types, so myStructInstance is a copy
		Dim anotherInstance As MyStruct = myStructInstance
		anotherInstance.MyField = 20
		' Changes to anotherInstance do not affect myStructInstance
		myStructInstance.Display()
		anotherInstance.Display()
	End Sub
End Class
$vbLabelText   $csharpLabel

C# 結構與類別(開發者運作方式):圖 2 - 從之前的代碼輸出的控制台結果

使用案例和指南

2.1. 何時使用類別

複雜狀態和行為: 當您需要建模具有狀態和行為的複雜資料結構時,請使用類別。 類別適用於表示具有多個屬性和方法的複雜對象。

參考語義:如果你想共享物件的實例並在程式碼的不同部分反映更改,類別是適合的選擇。

2.2. 何時使用結構體

簡單的數據結構:結構體對於較簡單的數據結構非常理想,這些結構體代表輕量級的實體,如小型數據結構,如點、矩形、鍵值對,或者如果結構體在邏輯上代表一個單一值,類似於原始類型。

值語義:當您偏好值語義並希望避免堆分配的開銷時,結構體是一個不錯的選擇。

性能考量:在性能至關重要的情況下,特別是對於小型且經常使用的物件,結構體由於堆疊配置而可能更加有效。

3. 記憶體分配差異

3.1. 類別

引用計數: 類別實例的記憶體由垃圾回收器通過引用計數來管理。 當物件不再有參考時,它們就符合垃圾回收的條件。

潛在的記憶體洩漏: 如果物件在不再需要時未正確處置,可能會導致記憶體洩漏。

3.2. 結構體

無垃圾回收:結構體是值類型,不依賴於垃圾回收,因為它們以不同的方式管理。 當它們超出作用域時會自動釋放。

有限的記憶體開銷:相較於類別,結構體具有較低的記憶體開銷,使其在記憶體使用受到關注的情況下更為高效。

4. 性能考量

類別

間接存取:由於類別實例是透過引用來訪問的,因此會有額外的間接層級,可能會導致輕微的性能開銷。

堆分配:堆中的動態記憶體分配可能導致較長的物件創建和銷毀時間。

結構體

直接訪問:直接訪問結構體,消除了額外間接層的需求。 這可以提高小型、經常使用的物件的性能。

堆疊分配:堆疊分配記憶體提供更快的 struct 實例建立和銷毀。

5. 介紹 IronPDF

IronPDF 體驗:強大的 C# PDF 操作函式庫 專為在 .NET 應用程式中實現無縫的 PDF 生成、操作和渲染而設計。 使用IronPDF,開發人員可以輕鬆地創建、修改和交互PDF文件,使其成為從HTML內容動態生成PDF到從現有文件中提取數據等任務的必備工具。 這個多功能庫簡化了與 PDF 相關的功能,為從事網頁應用程式、桌面軟體或任何需要高效 PDF 處理的 .NET 項目的開發人員提供了一整套全面的功能。

5.1. 安裝 IronPDF

在進入程式碼範例之前,您需要安裝IronPDF。 您可以使用 NuGet 套件管理器主控台完成此操作,或在您的專案中添加對 IronPDF 函式庫的引用。 以下步驟概述安裝過程:

  1. NuGet 套件管理器主控台:
    :ProductInstall
    :ProductInstall
SHELL
  1. 套件管理器 UI:在 NuGet 套件管理器 UI 中搜索 "IronPDF" 並安裝最新版本。

    安裝 IronPDF 後,您即可在 C# 應用程式中利用其 PDF 文件處理功能。

5.2. 使用結構體和類與IronPDF

using IronPdf;
using System;
// Sample class
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
// Sample struct
struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
}
class Program
{
    static void Main()
    {
        // Sample instances of class and struct
        Person person = new Person { Name = "John Doe", Age = 30 };
        Point point = new Point { X = 10, Y = 20 };
        // Create a new PDF document
        var renderer = new ChromePdfRenderer();
        // Add content with information from class and struct
        string content = $@"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>";
        // Render HTML content to PDF
        var pdf = renderer.RenderHtmlAsPdf(content);
        // Save the PDF to a file
        pdf.SaveAs("InformationDocument.pdf");
    }
}
using IronPdf;
using System;
// Sample class
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
// Sample struct
struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
}
class Program
{
    static void Main()
    {
        // Sample instances of class and struct
        Person person = new Person { Name = "John Doe", Age = 30 };
        Point point = new Point { X = 10, Y = 20 };
        // Create a new PDF document
        var renderer = new ChromePdfRenderer();
        // Add content with information from class and struct
        string content = $@"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>";
        // Render HTML content to PDF
        var pdf = renderer.RenderHtmlAsPdf(content);
        // Save the PDF to a file
        pdf.SaveAs("InformationDocument.pdf");
    }
}
Imports IronPdf
Imports System
' Sample class
Friend Class Person
	Public Property Name() As String
	Public Property Age() As Integer
End Class
' Sample struct
Friend Structure Point
	Public Property X() As Integer
	Public Property Y() As Integer
End Structure
Friend Class Program
	Shared Sub Main()
		' Sample instances of class and struct
		Dim person As New Person With {
			.Name = "John Doe",
			.Age = 30
		}
		Dim point As New Point With {
			.X = 10,
			.Y = 20
		}
		' Create a new PDF document
		Dim renderer = New ChromePdfRenderer()
		' Add content with information from class and struct
		Dim content As String = $"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>"
		' Render HTML content to PDF
		Dim pdf = renderer.RenderHtmlAsPdf(content)
		' Save the PDF to a file
		pdf.SaveAs("InformationDocument.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel
  • Person 是代表一個帶有 NameAge 屬性的人物的範例類別。
  • Point 是一個範例結構體,表示在 2D 坐標系統中的一個點,具有 XY 屬性。
  • 創建了Person類的實例和Point結構。
  • HTML內容隨後渲染成PDF文檔,並保存為 "InformationDocument.pdf"。

5.2.1. 輸出 PDF 文件

C# 結構體與類別(對開發人員的工作原理):圖 3 - 從前一段代碼輸出的 PDF 文件

6. 結論

總之,在使用 C# 結構與類別之間的選擇取決於您的應用程式的具體需求和特性。 類別作為參考型別,適合用於建模具有狀態和行為的複雜實體,支持繼承並促進共享實例。 另一方面,作為值類型的結構體非常適合具有值語義的輕量級數據結構,提供在棧分配和直接訪問方面的性能優勢。

IronPDF 為用戶提供免費試用許可證以供評估,這是一個了解 IronPDF 特性和功能的好機會。 要了解更多關於IronPDF的信息,請訪問詳細的IronPDF文檔,關於使用IronPDF創建PDF文件的詳細教程可在IronPDF PDF生成教程中找到。

Chipego
奇佩戈·卡林达
軟體工程師
Chipego 擁有天生的傾聽技能,這幫助他理解客戶問題,並提供智能解決方案。他在獲得信息技術理學學士學位後,于 2023 年加入 Iron Software 團隊。IronPDF 和 IronOCR 是 Chipego 專注的兩個產品,但隨著他每天找到新的方法來支持客戶,他對所有產品的了解也在不斷增長。他喜歡在 Iron Software 的協作生活,公司內的團隊成員從各自不同的經歷中共同努力,創造出有效的創新解決方案。當 Chipego 離開辦公桌時,他常常享受讀好書或踢足球的樂趣。
< 上一頁
C# 初始化陣列(開發人員如何操作)
下一個 >
NPlot C# (如何為開發者工作)