跳至頁尾內容
開發者更新

C# 密封類 (對開發者如何運作)

在物件導向程式設計的世界中,C#語言為開發者提供了一套多功能的工具來設計和實現健全的軟體。 其中一個為類別繼承新增額外控制層的功能就是密封類別的概念。 密封類別提供了一種限制繼承層次結構的獨特方式,提供了一定程度的安全性和封裝,在某些情況下非常有利。 在本文中,我們將深入探討C#密封類別的複雜性,並探索來自Iron SoftwareIronPDF NuGet包。

什麼是密封類別和密封方法?

密封類別:在C#中,密封類別是一種不能被繼承的類別。 通過使用sealed關鍵字,開發者可以防止其他類別從密封類別派生或擴展。 這種有意的限制確保了密封類別不能作為任何其他類別的基礎類別,限制了繼承層次結構的範圍。 當開發者希望控制和最終確定類別的結構時,通常會使用密封類別,以防止通過繼承進行非預期的修改。

請考慮以下範例:

public sealed class Animal
{
    public string Species { get; set; }

    public void MakeSound()
    {
        Console.WriteLine("Generic animal sound");
    }
}

// The following code will cause a compilation error because 'Animal' is sealed and cannot be inherited:
// public class Dog : Animal // Error: Cannot inherit from sealed class 'Animal'
// {
// }
public sealed class Animal
{
    public string Species { get; set; }

    public void MakeSound()
    {
        Console.WriteLine("Generic animal sound");
    }
}

// The following code will cause a compilation error because 'Animal' is sealed and cannot be inherited:
// public class Dog : Animal // Error: Cannot inherit from sealed class 'Animal'
// {
// }
Public NotInheritable Class Animal
	Public Property Species() As String

	Public Sub MakeSound()
		Console.WriteLine("Generic animal sound")
	End Sub
End Class

' The following code will cause a compilation error because 'Animal' is sealed and cannot be inherited:
' public class Dog : Animal // Error: Cannot inherit from sealed class 'Animal'
' {
' }
$vbLabelText   $csharpLabel

與甚至隱式密封的結構體不同,密封類別必須如上所示使用sealed關鍵字來聲明。 在這個例子中,Animal類別被聲明為密封,使得其他類別無法從中繼承。

密封方法:除了封裝整個類別,C#還允許開發者在類別內封裝單獨的方法。 密封方法是一種派生類別不能覆蓋的方法。這確保了方法的行為在所有子類別中保持一致,為應用程式的邏輯提供了一定的可預測性。

若要隱藏方法,使用sealed修飾符:

public class Animal
{
    public string Species { get; set; }

    // A virtual method allows derived classes to override it.
    public virtual void MakeSound()
    {
        Console.WriteLine("Generic animal sound");
    }
}

public class Dog : Animal
{
    // The sealed override prevents further overriding of this method.
    public sealed override void MakeSound()
    {
        Console.WriteLine("Bark!");
    }
}
public class Animal
{
    public string Species { get; set; }

    // A virtual method allows derived classes to override it.
    public virtual void MakeSound()
    {
        Console.WriteLine("Generic animal sound");
    }
}

public class Dog : Animal
{
    // The sealed override prevents further overriding of this method.
    public sealed override void MakeSound()
    {
        Console.WriteLine("Bark!");
    }
}
Public Class Animal
	Public Property Species() As String

	' A virtual method allows derived classes to override it.
	Public Overridable Sub MakeSound()
		Console.WriteLine("Generic animal sound")
	End Sub
End Class

Public Class Dog
	Inherits Animal

	' The sealed override prevents further overriding of this method.
	Public NotOverridable Overrides Sub MakeSound()
		Console.WriteLine("Bark!")
	End Sub
End Class
$vbLabelText   $csharpLabel

sealed關鍵字阻止進一步覆蓋在任何後續子類中基類的虛擬方法。

密封類別和類別成員:密封類別也可以包括密封成員,如屬性、方法和事件。 這種密封類別和密封成員的組合確保了對類別行為和結構的高度控制。

請考慮以下範例:

public sealed class ControlledClass
{
    // A sealed property that prevents overriding.
    public sealed string ControlledProperty { get; set; }

    // A method that cannot be redefined by derived classes.
    public virtual sealed void ControlledMethod()
    {
        // Method implementation
        Console.WriteLine("Executing controlled method.");
    }

    // A sealed event that cannot be subscribed to or raised by derived classes.
    public sealed event EventHandler ControlledEvent;

    // Sealed indexers, if applicable
    public sealed string this[int index]
    {
        get { return "Value"; }
        set 
        { 
            // Setter implementation 
        }
    }
}
public sealed class ControlledClass
{
    // A sealed property that prevents overriding.
    public sealed string ControlledProperty { get; set; }

    // A method that cannot be redefined by derived classes.
    public virtual sealed void ControlledMethod()
    {
        // Method implementation
        Console.WriteLine("Executing controlled method.");
    }

    // A sealed event that cannot be subscribed to or raised by derived classes.
    public sealed event EventHandler ControlledEvent;

    // Sealed indexers, if applicable
    public sealed string this[int index]
    {
        get { return "Value"; }
        set 
        { 
            // Setter implementation 
        }
    }
}
Public NotInheritable Class ControlledClass
	' A sealed property that prevents overriding.
	Public NotOverridable Property ControlledProperty() As String

	' A method that cannot be redefined by derived classes.
	Public Overridable NotOverridable Sub ControlledMethod()
		' Method implementation
		Console.WriteLine("Executing controlled method.")
	End Sub

	' A sealed event that cannot be subscribed to or raised by derived classes.
	Public Event ControlledEvent As EventHandler

	' Sealed indexers, if applicable
	Default Public NotOverridable Property Item(ByVal index As Integer) As String
		Get
			Return "Value"
		End Get
		Set(ByVal value As String)
			' Setter implementation 
		End Set
	End Property
End Class
$vbLabelText   $csharpLabel

在這個例子中,ControlledClass 的每個方面都是密封的——屬性、方法、事件,甚至在適用的情況下可能還有索引器。 這種密封程度提供了一個健全且不可更改的結構,對於類別設計應保持固定不變的情況下是理想的。

密封類別的合理性

程式碼安全性:密封類別通過防止未經授權的存取和修改來促進程式碼安全性。 當類別被密封時,它作為一個封閉實體,具有明確定義的介面和行為。 這種封裝可最大限度地減少未預期的副作用或可能危害程式碼庫穩定性和安全性的變更風險。

設計完整性:在較大的程式碼庫或框架中,保持設計完整性至關重要。 密封類別作為具有固定結構的基礎構建塊,減少了意外修改的可能性。 這特別有利於類別作為系統的核心組件的場景,其行為應在不同模塊間保持一致。

使用密封類別的最佳實踐

  1. 謹慎使用密封類別:儘管密封類別具有優勢,但應謹慎使用。 過度使用密封類別可能會導致程式碼僵化且維護性差。
  2. 記錄意圖:當密封一個類別或方法時,記錄這一決定背後的意圖至關重要。 說明為什麼某個類別被密封,以及是什麼設計考量導致了這一選擇。
  3. 考慮未來的擴展性:在封裝類別之前,考慮將來的需求是否可能需要擴展性。 如果有可能需要擴展類別,密封它可能會妨礙未來的發展。
  4. 使用密封方法來穩定性:當希望方法的核心行為在不同子類別中保持穩定時,密封方法可能是有益的。 這可以增強程式碼的可預測性。
  5. 它不能同時是抽象的:密封類別/密封方法不能同時是抽象類別/抽象方法,因為抽象類別設計為可被其他類別繼承,而密封類別限制了繼承。

介紹IronPDF

C# Sealed Class (如何運作於開發者): 圖1 - IronPDF 網頁

IronPDF 是來自Iron Software的一個C# PDF程式庫,是一個現代的PDF生成和閱讀器。

安裝

IronPDF可以使用NuGet包管理員控制台或使用Visual Studio包管理員來安裝。 以下是用於控制台的命令:

Install-Package IronPdf

或者,若要使用NuGet包管理員安裝IronPDF,請在NuGet包管理員的搜尋欄中搜尋"IronPDF"。

C# Sealed Class (如何運作於開發者): 圖2 - 透過NuGet包管理員安裝IronPDF程式庫

IronPDF 和密封類別

密封關鍵字與 IronPDF 結合使用,可防止子類別程式庫或派生程式庫覆蓋繼承的成員,也可生成PDF。

namespace OrderBy
{
    public class Program
    {
        static void Main()
        {
            Console.WriteLine("Demo Sealed Class and IronPdf");
            var dog = new Dog();
            dog.MakeSound();
            dog.Print();
        }
    }

    // Base class
    public class Animal
    {
        public string Species { get; set; }

        public virtual void MakeSound()
        {
            Console.WriteLine("Generic animal sound");
        }

        public virtual void Print()
        {
            Console.WriteLine("Generic animal Print");
        }
    }

    public class Dog : Animal
    {
        // Sealed override ensures method cannot be overridden in further derived classes.
        public sealed override void MakeSound()
        {
            Console.WriteLine("Bark!");
        }

        public sealed override void Print()
        {
            var pdfRenderer = new ChromePdfRenderer();
            string content = @"
            <!DOCTYPE html>
            <html>
            <body>
                <h1>Hello, Dog!</h1>
                <p>This is Print from Derived class.</p>
                <p>Print Animal Dog</p>
                <p>Print Animal Sound: Bark</p>
            </body>
            </html>";

            pdfRenderer.RenderHtmlAsPdf(content).SaveAs("dog.pdf");
        }
    }
}
namespace OrderBy
{
    public class Program
    {
        static void Main()
        {
            Console.WriteLine("Demo Sealed Class and IronPdf");
            var dog = new Dog();
            dog.MakeSound();
            dog.Print();
        }
    }

    // Base class
    public class Animal
    {
        public string Species { get; set; }

        public virtual void MakeSound()
        {
            Console.WriteLine("Generic animal sound");
        }

        public virtual void Print()
        {
            Console.WriteLine("Generic animal Print");
        }
    }

    public class Dog : Animal
    {
        // Sealed override ensures method cannot be overridden in further derived classes.
        public sealed override void MakeSound()
        {
            Console.WriteLine("Bark!");
        }

        public sealed override void Print()
        {
            var pdfRenderer = new ChromePdfRenderer();
            string content = @"
            <!DOCTYPE html>
            <html>
            <body>
                <h1>Hello, Dog!</h1>
                <p>This is Print from Derived class.</p>
                <p>Print Animal Dog</p>
                <p>Print Animal Sound: Bark</p>
            </body>
            </html>";

            pdfRenderer.RenderHtmlAsPdf(content).SaveAs("dog.pdf");
        }
    }
}
Namespace OrderBy
	Public Class Program
		Shared Sub Main()
			Console.WriteLine("Demo Sealed Class and IronPdf")
			Dim dog As New Dog()
			dog.MakeSound()
			dog.Print()
		End Sub
	End Class

	' Base class
	Public Class Animal
		Public Property Species() As String

		Public Overridable Sub MakeSound()
			Console.WriteLine("Generic animal sound")
		End Sub

		Public Overridable Sub Print()
			Console.WriteLine("Generic animal Print")
		End Sub
	End Class

	Public Class Dog
		Inherits Animal

		' Sealed override ensures method cannot be overridden in further derived classes.
		Public NotOverridable Overrides Sub MakeSound()
			Console.WriteLine("Bark!")
		End Sub

		Public NotOverridable Overrides Sub Print()
			Dim pdfRenderer = New ChromePdfRenderer()
			Dim content As String = "
            <!DOCTYPE html>
            <html>
            <body>
                <h1>Hello, Dog!</h1>
                <p>This is Print from Derived class.</p>
                <p>Print Animal Dog</p>
                <p>Print Animal Sound: Bark</p>
            </body>
            </html>"

			pdfRenderer.RenderHtmlAsPdf(content).SaveAs("dog.pdf")
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel

C# Sealed Class (如何運作於開發者): 圖3 - 控制台輸出,顯示執行指令和任何結果控制台消息

以下是IronPDF生成的PDF

C# Sealed Class (如何運作於開發者): 圖4 - 使用之前的程式碼範例生成的PDF輸出

授權(提供免費試用)

IronPDF. 此鑰匙需要放在 appsettings.json 中。

{
    "IronPdf.LicenseKey": "your license key"
}

提供您的電子郵件以獲取試用許可。

結論

C#密封類別為開發者提供了一種強大的機制來控制繼承層次結構,確保某些類別及其成員不能被擴展或覆蓋。 雖然應慎重考慮密封類別的使用,但它們提供了一種有效的方式來封裝功能和防止非預期的更改。 通過理解密封類別和方法的概念,開發者可以就何時何地應用這一限制做出明智決策,協助建立可維護、安全和可預測的軟體系統。 與 IronPDF 一起,我們還可以列印PDF文件。

常見問題

密封類別在C#中如何運作?

在C#中,使用sealed關鍵字來定義密封類別。這可以防止其他類別繼承自該類別,確保類別的實現保持不變。

為什麼開發者應該在C#中使用密封類別?

密封類別用於通過防止繼承來維護程式碼的完整性。這確保了類別的行為保持一致和安全,特別是在設計完整性至關重要的大型系統中。

密封類別可以有封閉的方法嗎?

可以的,密封類別可以包含本身也是封閉的方法。這意味著在派生類別中的方法不能被覆寫,進一步增強了類別功能的安全性和一致性。

在類別中使用密封方法有什麼好處?

密封方法可以防止派生類別覆寫,這有助於保持方法的原始行為,確保一致性並防止未預期的修改。

您能舉例說明何時使用密封類別嗎?

當您希望鎖定類別的實現以防止通過繼承進行更改時,密封類別非常有用,例如在工具類別中或涉及需要穩定的敏感操作時。

密封類別與C#中的PDF生成有何關係?

當使用PDF程式庫如IronPDF時,密封類別可以被利用來確保PDF生成過程的一致性和安全性,通過防止繼承修改。

是否可以將密封類別與IronPDF等第三方程式庫一起使用?

可以的,密封類別可以與IronPDF等第三方程式庫一起使用,以將PDF生成邏輯封裝在安全、不可繼承的類別結構中。

如何使用NuGet安裝C# PDF程式庫?

您可以使用dotnet add package IronPdf命令通過NuGet套件管理器安裝C# PDF程式庫,如IronPDF,或在Visual Studio NuGet套件管理器中搜尋'ironpdf'。

使用密封類別在軟體設計中需要考慮哪些因素?

開發者應考慮未來的可擴展性並記錄密封類別的原因。使用密封類別可以增強安全性和可維護性,但應與應用程式所需的靈活性平衡。

對於C#開發者,推薦使用哪一款PDF生成器?

IronPDF是一款推薦給C#開發者的PDF生成器,提供強大的PDF建立和操作功能,作為一個NuGet套件。

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天。
聊天
電子郵件
給我打電話