枚举类型和帮助程序的可见性

时间:2018-01-04 11:56:12

标签: delphi delphi-10.2-tokyo

我有一些基本单元,我需要将它们分开,但为了便于使用,我想将它们分成一个单元。现在我有枚举类型和帮助器的问题,不知道是否还有其他问题。是否有可能使这项工作?

的BaseUnit

type
  TCustomEnum = (ceValue1, ceValue2, ceValue3);

TCustomEnumHelper = record helper for TCustomEnum
  function AsString: string;
end;

GroupUnit

uses BaseUnit;

TCustomEnum = BaseUnit.TCustomEnum; 

在其他单位使用。

uses GroupUnit;

procedure DoSomething;
var
  lValue : TCustomEnum;
begin
  lValue := ceValue1; // doesn't work
  lValue := TCustomEnum.ceValue1; // works 
  lValue.AsString; // doesn't work
end;

1 个答案:

答案 0 :(得分:3)

您的实验已经完全符合预期。

您的第三个单元有权访问TCustomEnum的唯一原因是GroupUnit使用相同的标识符声明了类型别名,但仅使用该标识符。值得注意的是,这是Delphi编译过程与C ++不同的重要方式。 C ++以递归方式将所有包含引入编译范围,而Delphi只引入直接包含单元的接口部分。

  • lValue := ceValue1;无法正常工作,因为ceValue1未在编译范围内定义。
  • lValue := TCustomEnum.ceValue1;有效,因为TCustomEnum完全被拉入。这是因为TCustomEnum 等于 BaseUnit.TCustomEnum:这意味着TCustomEnum.ceValue1必须有效。
    1. 您应该注意与对象和记录类似。即使您只提取类/记录类型,也可以始终引用公共成员。
    2. 这与前一个案例不同,因为您使用ceValue1而没有任何资格。并且在范围内没有对该标识符的无限定义。
  • lValue.AsString;这不起作用,因为使AsString可用的帮助程序不在范围内。

在某些情况下,声明类型别名可能很有用。但我必须指出,通用分组单元的思想存在严重缺陷。

是的,它确实减少了使用所需的单位数量,以便提取 1 数量的依赖关系。即您认为通过将uses Unit1, Unit2, Unit3, Unit4, Unit5, Unit6;替换为较短的uses GroupUnit;来节省时间。

但是,大的 1 依赖关系意味着你还引入了你不需要的东西。这导致:

  • 管理不善的架构,其中一切都间接依赖于其他一切。 (或称为"泥球大球" 建议研究。)
  • 不必要的间接水平;这意味着如果你想找到你正在使用的东西的定义,你Find declaration...只能找到别名,并且必须再次Find declaration...找到你真正想要的东西。

是的,列出您正在使用的每件事情似乎更多的工作。但是,如果您使用那么多令人沮丧的事情,您应该问自己:为什么我的课程如此复杂?然后我的错误是什么?设计;我该如何改进?

作为最后一点,你可以使用别名而不仅仅是enum;只要你明确这样做。

以下可能就足够了(但请再次谨慎使用)。 尤其是因为它做了这么多工作。

unit GroupUnit;

interface

uses BaseUnit;

type
  TCustomEnum = BaseUnit.TCustomEnum;
  TCustomEnumHelper = BaseUnit.TCustomEnumHelper;
const
  ceValue1 = BaseUnit.ceValue1;
  ceValue2 = BaseUnit.ceValue2;
  ceValue3 = BaseUnit.ceValue3;