如果显式调用 Create,我可以让编译器失败吗?

Can I make the compiler fail if Create is called explicitly?

我有很多单例,我不希望开发人员调用构造函数 Create。相反,他们应该使用函数 Instance

TdgpBankBranch = class(TDataGroup)
strict private
  class var InstanceVar : TdgpBankBranch;
private
  { Only for internal use }
  constructor Create (AOwner : TComponent); reintroduce;
protected
public
  class function Instance : TdgpBankBranch;
  class function Is_A_Live_Singleton: boolean;
  property Rec[Bank, Branch : integer]: TBankBranch read GetRec; default;
end;

我一直在将构造函数转移到 private。这让代码分析者抱怨 "Non-public constructor".

我可以将它们移回 public。如果尝试使用 constructor,有没有办法让编译器失败?

将构造函数移动到 private 将阻止其他单元直接调用 Create(),但是与 class 相同单元内的代码仍然可以调用它由于单位内的隐性友谊,不受阻碍。如果您不希望 class 之外的任何代码直接调用 Create(),即使在同一单元中,则将其声明为 strict private,这样只有 class 本身可以调用直接。

你问如何在有人调用 .create 时阻止编译器创建对象,但你想做的是创建一个单例,所以看看其他人是如何解决这个问题的。

在 Delphi 中,单例通常通过在接口部分声明的函数实现,而 returns 在单元的实现部分声明一个对象。如果实例不存在,该函数会创建实例,以提供延迟加载。清理是通过完成部分完成的。

在您的情况下,您无需使用 instance() 函数,只需创建一个为您提供实例的全局函数。

这种方法可能起源于 classes 和私人部分存在之前的日子,但它非常简单,并且可以防止您 运行 遇到的问题。看看TClipboard是如何实现的。这种实现在 Java 或 C# 中是不可能的,因为它们没有全局函数,或者使这种 Delphi 实现工作的作用域类型...

或者看看 David Heffernan 的回答: Delphi Singleton Pattern

它甚至比 TClipboard 更好,因为它将整个 class 隐藏在实现部分,真正防止人们自己创建实例,但您必须为您的 class 创建一个接口.