Delphi - Как вы разрешаете конфликт, когда имя элемента совпадает с именем свойства?
Тривиальный пример ниже - это конденсация проблемы, с которой я пытался разрешить конфликт, когда у меня был элемент перечисленного типа с тем же именем, что и член VCL.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
TSomeType = (
alNone,
alSome,
alMany) ;
procedure TForm1.FormCreate(Sender: TObject);
begin
Self.Align := alNone ; // 1. type mismatch
Self.Align := Controls.alNone ; // 2. "Controls" is also a property of TForm
end ;
end.
- Первое присваивание не выполняется, потому что компилятор считает, что
alNone
- это тот, который я объявил, а не элемент TAlign
, определенный в Controls.pas
.
- Второе неудачно, потому что для
TForm
для этого имени требуется Controls
.
Я понимаю, что есть способы обойти это (переименование элемента alNone
является самым простым), но мне любопытно, есть ли способ присвоить ссылку на свойство в другом блоке, где имя элемента конфликтует с идентификатор в текущей области.
Ответы
Ответ 1
Отметьте его именем типа:
TAlign.alNone
Я не понял, когда написал это, что актуальна версия компилятора. Этот синтаксис стал доступен только в Delphi 2010 или XE. Там ответ не подходит для помеченной версии, Delphi 2007. Deltics ответ охватывает гораздо более подробно.
Ответ 2
Как подсказывает Дэвид, для типа перечисления или другой ситуации, когда тип может использоваться для квалификации идентификатора, то вы, конечно, можете просто использовать имя типа по мере необходимости:
someAlign := TAlign.alNone;
someMyType := TMyType.alNone;
Это использование перечислений называется scobe enums" и не поддерживается в более старых версиях компилятора Delphi. Я считаю, что XE2 возможно, когда он был введен. Конечно, это была версия, которая сделала обязательные по умолчанию перечисления обязательными по умолчанию.
Хотя его можно отключить с помощью директивы компилятора. Когда вы выключены, вы все равно можете использовать скопированные перечисления, но вам не требуется.
В версиях, которые поддерживают это, вы должны квалифицировать все перечисления, которые определены во время включения. Вы можете выбрать качество или нет при использовании перечислений, которые определены, когда это отключено.
type
{$SCOPEDENUMS ON}
TFoo = (Black, White); // MUST qualify: eg. "TFoo.Black"
{$SCOPEDENUMS OFF}
TBar = (Black, White); // MAY qualify or not if/as needed
Для более старых версий Delphi без поддержки области enum или в ситуациях, когда идентификатор не является членом перечисления и в противном случае не может быть квалифицирован по типу - например, если ваши идентификаторы конфликтуют с некоторым идентификатором на уровне единицы (например, например, mrOk
, в Элементы управления), вам нужно немного больше работать, но не много.
В этих случаях просто определите новую константу, чтобы создать однозначный "локальный псевдоним" для константы в другом блоке и ввести это, когда имя единицы однозначно. Похоже на:
type
TMyResult = (
mrOk,
mrFailed) ;
const
Controls_mrOk = Controls.mrOk; // mrOk is a const, not an enum member