为什么 delphi 使用类型别名,如果这被证明不是一个好方法?

why delphi use type alias if this was proven to not be a good approach?

每年我都在尝试做一些事情,因为这个问题显示 How do I use enum values when their type is defined indirectly in another unit? 其他用户鼓励我放弃这种心态,因为出于各种原因这不是一个好方法。

好吧,几天前我在为我们的软件做一些自定义对话框,我想使用 delphi 原生提供的一些类型,而不是声明我自己的。令我惊讶的是,文件 vcl.dialogs 具有我被鼓励不要使用的相同技术,如代码所示:

{ Message dialog }
mtWarning   = System.UITypes.TMsgDlgType.mtWarning;
mtError = System.UITypes.TMsgDlgType.mtError;
mtInformation   = System.UITypes.TMsgDlgType.mtInformation;
mtConfirmation  = System.UITypes.TMsgDlgType.mtConfirmation;
mtCustom    = System.UITypes.TMsgDlgType.mtCustom;

mbYes   = System.UITypes.TMsgDlgBtn.mbYes;
mbNo    = System.UITypes.TMsgDlgBtn.mbNo;
mbOK    = System.UITypes.TMsgDlgBtn.mbOK;
mbCancel    = System.UITypes.TMsgDlgBtn.mbCancel;
mbAbort = System.UITypes.TMsgDlgBtn.mbAbort;
mbRetry = System.UITypes.TMsgDlgBtn.mbRetry;
mbIgnore    = System.UITypes.TMsgDlgBtn.mbIgnore;
mbAll   = System.UITypes.TMsgDlgBtn.mbAll;
mbNoToAll   = System.UITypes.TMsgDlgBtn.mbNoToAll;
mbYesToAll  = System.UITypes.TMsgDlgBtn.mbYesToAll;
mbHelp  = System.UITypes.TMsgDlgBtn.mbHelp;
mbClose = System.UITypes.TMsgDlgBtn.mbClose;

所以基本上 delphi 将最初在 System.UITypes 上声明的这种类型复制到 vcl.dialogs 文件中。

所以问题是:他为什么这样做有合理的解释吗? delphi 写错了吗?这种做法是不是很糟糕?如果没有足够的方法来使用它?

有更好的方法可以完成您想要完成的任务。在不同的单元中使用相同的枚举类型会导致维护问题,而您实际上并不需要它来完成您想要完成的任务。

据我所知,没有更好的方法可以完成 VCL 开发人员想要完成的任务。 VCL 开发人员 do 确实需要相同的枚举类型在两个独立的单元中可用,并准备好处理由此引起的任何维护困难。如果这是任何其他库,他们可以说 "just add System.UITypes to your uses list",并从 Vcl.Dialogs 中删除类型。然而,VCL 努力保持兼容性,以确保用旧版本 Delphi 编译的代码仍然可以用更高版本编译。它需要这样做,因为任何无法编译的先前有效代码都是潜在的客户流失,Delphi 本身远比各种第三方库更是如此。

这些不是类型别名。这些实际上是常数。更重要的是,这些是真正的常量而不是类型常量。这意味着您可以导入 Vcl.DialogsSystem.UITypes 并使用 mtWarning.

Embarcadero 这样做是为了允许跨平台使用这种类型,同时保持与现有代码的向后兼容性。引入 FireMonkey 时出现了跨平台需求。

需要在 Windows 以外的平台上使用此类型。但是,VCL 仅为 Windows。所以在 VCL 命名空间单元中声明类型是行不通的。因此引入了 System.UITypes。为了允许现有代码继续编译,设计者选择从 Vcl.Dialogs.

导出相同的值

新代码应使用 System.UITypes 来访问此枚举类型。

解释很简单——有太多旧代码对“'System.UITypes'”和“'vcl.dialogs'”一无所知。他们只知道“'dialogs'”模块。

而且这个旧程序仍然可以编译并且运行。所以我认为它只是向后兼容并为跨平台开发做准备。