Ваши эксперименты дали именно то, что и следовало ожидать.
Единственная причина, по которой ваш третий модуль имеет доступ к TCustomEnum
, заключается в том, что GroupUnit
объявил псевдоним типа, используя тот же идентификатор, но только этот идентификатор. Важно отметить, что это важное отличие процесса компиляции Delphi от C++. В то время как C++ рекурсивно извлекает все включения в область компиляции, Delphi извлекает только раздел interface непосредственно включенных модулей.
lValue := ceValue1;
не работает, потому что ceValue1
не определено в области компиляции.
lValue := TCustomEnum.ceValue1;
works because TCustomEnum
is pulled in in its entirety. That's to say because TCustomEnum
is equal to BaseUnit.TCustomEnum
: it means TCustomEnum.ceValue1
must be valid.
- You should note similar with objects and records. You can always reference public members, even if you only pull in the class/record type.
- Это отличается от предыдущего случая, потому что вы использовали
ceValue1
без никакого уточнения. И нет однозначного определения для этого идентификатора в области видимости.
lValue.AsString;
это не работает, потому что помощник, который делает AsString
доступным, не входит в область действия.
Бывают ситуации, когда объявление псевдонимов типов может быть полезным. Но я должен отметить, что идея группировки общего назначения глубоко ошибочна.
Да, это уменьшает количество единиц, которые вы должны использовать, чтобы получить большое1 количество зависимостей. т.е. Вы думаете, что экономите время, заменяя uses Unit1, Unit2, Unit3, Unit4, Unit5, Unit6;
более коротким uses GroupUnit;
.
Но большие зависимости1 означают, что вы также добавили то, что вам не нужно. Это ведет к:
- Плохо управляемая архитектура, где все косвенно зависит почти от всего остального. (Иначе известный как "Большой ком грязи" рекомендуемое исследование.)
- Ненужные уровни косвенности; это означает, что если вы хотите найти определение того, что вы используете, вы
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;
person
Disillusioned
schedule
04.01.2018
.AsString
имеет к вашему вопросу? Это кажется совершенно не связанным. Может ли это быть потому, что в предыдущей строке отсутствует точка с запятой? - person Jerry Dodge   schedule 04.01.2018