为什么 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.Dialogs
或 System.UITypes
并使用 mtWarning
.
Embarcadero 这样做是为了允许跨平台使用这种类型,同时保持与现有代码的向后兼容性。引入 FireMonkey 时出现了跨平台需求。
需要在 Windows 以外的平台上使用此类型。但是,VCL 仅为 Windows。所以在 VCL 命名空间单元中声明类型是行不通的。因此引入了 System.UITypes
。为了允许现有代码继续编译,设计者选择从 Vcl.Dialogs
.
导出相同的值
新代码应使用 System.UITypes
来访问此枚举类型。
解释很简单——有太多旧代码对“'System.UITypes'”和“'vcl.dialogs'”一无所知。他们只知道“'dialogs'”模块。
而且这个旧程序仍然可以编译并且运行。所以我认为它只是向后兼容并为跨平台开发做准备。
每年我都在尝试做一些事情,因为这个问题显示 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.Dialogs
或 System.UITypes
并使用 mtWarning
.
Embarcadero 这样做是为了允许跨平台使用这种类型,同时保持与现有代码的向后兼容性。引入 FireMonkey 时出现了跨平台需求。
需要在 Windows 以外的平台上使用此类型。但是,VCL 仅为 Windows。所以在 VCL 命名空间单元中声明类型是行不通的。因此引入了 System.UITypes
。为了允许现有代码继续编译,设计者选择从 Vcl.Dialogs
.
新代码应使用 System.UITypes
来访问此枚举类型。
解释很简单——有太多旧代码对“'System.UITypes'”和“'vcl.dialogs'”一无所知。他们只知道“'dialogs'”模块。
而且这个旧程序仍然可以编译并且运行。所以我认为它只是向后兼容并为跨平台开发做准备。