我有几个基本单位,我需要将其分开,但是为了易于使用,我想将它们分组为一个单位。目前,我对枚举类型和助手有疑问,不确定是否还有其他问题。有可能使这项工作吗?

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;

最佳答案

您的实验已经产生了预期的结果。

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


lValue := ceValue1;不起作用,因为在编译范围中未定义ceValue1
lValue := TCustomEnum.ceValue1;之所以有效,是因为TCustomEnum是全部插入的。这是因为TCustomEnum等于BaseUnit.TCustomEnum:这意味着TCustomEnum.ceValue1必须有效。


您应该注意与对象和记录类似的东西。即使您仅拉入班级/记录类型,也可以始终引用公共成员。
这与先前的情况不同,因为您使用ceValue1时没有任何限制。并且在范围内没有对该标识符的无条件定义。

lValue.AsString;这不起作用,因为使AsString可用的帮助程序不在范围内。




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

是的,它确实减少了为了获取大量依赖项而必须使用的单元数。即您认为用较短的uses Unit1, Unit2, Unit3, Unit4, Unit5, Unit6;替换uses GroupUnit;可以节省时间。

但是large1依赖项意味着您还引入了不需要的东西。这导致:


管理不善的体系结构,其中所有内容间接依赖于几乎所有其他内容。 (否则称为“泥浆大球”建议进行研究。)
不必要的间接级别;意思是,如果您要查找所用对象的定义,则只需Find declaration...即可获得别名,而必须再次Find declaration...来查找实际需要的内容。


是的,列出您正在使用的每件事似乎都需要更多工作。但是,如果您使用的很多东西令人沮丧,那么您应该问自己:为什么我的课程如此复杂?然后我的设计出了什么问题?我该如何改善?



最后一点,您不仅可以给枚举别名,还可以为别名加别名。只要您明确地这样做。

以下内容可能就足够了(但还是要谨慎使用)。尤其是因为它需要大量工作。

unit GroupUnit;

interface

uses BaseUnit;

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

10-06 01:04