C# 中的 Singleton 类为何被密封?

2025年2月5日 | 阅读5分钟

为何需要 Singleton 设计模式?

  • C# 中的 Singleton 类通常被密封以防止继承。使用 Singleton 设计模式,一个类可以保证只生成自身的一个实例,并提供该实例的全局访问点。
  • 当一个类被密封时,其他类就不能继承它。这对于维护 Singleton 模式至关重要,因为允许继承可能会通过创建 Singleton 类的多个实例来破坏 Singleton 原则。
  • 密封类可防止其被子类化,从而使您能够控制实例化过程,并确保在应用程序的整个生命周期中只有一个类的实例。

C# 中的 Singleton 类为何被密封?

为了确保一个类只能存在一个实例并防止它们被继承,C# 中的 Singleton 类通常被声明为“密封”。当一个类被密封时,它就不能被其他类继承,这可以防止任何人创建子类并可能引入 Singleton 的多个实例。

让我们通过一个例子来探讨 C# 中的 Singleton 类为何被密封。

首先,不使用 `sealed` 关键字来构造 Singleton 类。

此时,您将收到以下编译错误。由于其保护级别,“Singleton.Singleton()”无法访问。

Singleton 类中的私有构造函数导致了上述问题。您可能想知道,为什么 Singleton 类需要 `sealed` 关键字,因为由于类的私有构造函数,它很难被继承。

C# 中的嵌套类是什么?

在 C# 中,将一个类定义在另一个类内部所产生的内部优雅被称为嵌套类或内部类。现在,如果我们编译这个程序,就可以停止收到错误。

让我们修改 Program 类的 Main 方法来访问嵌套类。

结果清楚地表明,私有构造函数运行了两次,创建了 Singleton 类的多个实例。计数器的值已增加到 2。因此,通过删除 `sealed` 关键字,我们可以继承 Singleton 类并创建它的多个实例。然而,这破坏了 Singleton 设计原则。如下所示,让我们密封 Singleton 类。然后,让我们编译程序并观察会发生什么。

在程序编译过程中,我们遇到了一个错误,表明我们无法从一个密封类派生。因此,我们可以推断 `sealed` 关键字在 C# 中将阻止类继承,而私有构造函数将帮助我们阻止对类的任何外部实例化。

上述 Singleton 实现不是线程安全的。Singleton 类的实现使得 `if (instance == null)` 条件能够被两个不同的线程同时评估并确定为 true。它们都会创建违反 Singleton 设计原则的实例。

为什么 C# 中的 Singleton 类通常被密封?

以下是 C# 中 Singleton 类通常被密封的几个原因:

  • 维护 Singleton 的语义: Singleton 模式旨在确保一个类在应用程序的整个生命周期内只有一个实例。通过密封类,您可以避免在有人尝试继承 Singleton 类并创建自己的实例时可能发生的某些问题。
  • 阻止子类化: 如果一个 Singleton 类没有被密封,就不能被子类化。子类化可能会破坏 Singleton 模式的意图,并导致创建额外的类实例。通过密封类,可以避免这种情况。
  • 强制执行设计目标: 通过向其他开发人员明确表示一个类应该只有一个实例,密封 Singleton 类可以强制执行 Singleton 模式的设计目标。它传达了类的预期行为和用法。

将类声明为密封可确保遵循 Singleton 模式并且不能被继承。由于在程序生命周期中只有一个类的实例,开发人员会发现它更容易使用,并且知道其行为是恒定的。

当然!让我们更深入地探讨密封 Singleton 类的重要性以及它如何影响该类只有一个实例的保证。

  • 防止子类化: 在 C# 中,您可以密封一个类以防止其他类继承它。这意味着任何子类都不能修改其行为或添加新的实例化逻辑。这对于 Singleton 类很重要,因为允许子类化可能会通过子类构造函数创建多个实例。
  • 提供对单个实例的全局访问点: Singleton 模式的根本思想是保证一个类只有一个实例。密封类可以防止任何其他类通过继承或任何其他方法创建额外的实例,有助于强制执行此概念。
  • 控制实例化: 通过密封 Singleton 类,您可以控制实例的创建和访问。Singleton 类通常包含一个静态函数或属性,用于提供对单个实例的访问,并且通常有一个私有构造函数来阻止外部实例化。密封类确保 Singleton 模式得到正确应用并加强了这种封装。
  • 线程安全: 在多线程环境中,需要确保 Singleton 实例以线程安全的方式生成,以避免竞争条件。通过密封类,您可以避免考虑子类化可能性,这可能会使同步更加复杂。这使得实现线程安全机制更加容易。

总而言之,密封 C# Singleton 类是一种最佳实践,它强调了控制、线程安全和封装的概念——所有这些对于成功实现 Singleton 模式都至关重要。

结论

总之,密封 C# Singleton 类是一项基本过程,它支持维护 Singleton 模式的完整性。它通过禁止子类化来确保在程序整个生命周期中只有一个类的实例。这种实例化控制可以提高线程安全性,简化实现,并有助于封装。

密封类是构建可靠且可维护软件系统的基本组成部分,因为它重申了 Singleton 模式的关键思想,即保证单个实例的生成并提供对该实例的全局访问。