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