Delphi - 当单位名称与 属性 名称相同时如何解决冲突?

Delphi - How do you resolve a conflict when a unit name is the same as a property name?

下面这个简单的例子是我试图解决冲突的一个问题的浓缩,在这个冲突中我有一个与 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.alNone

写这篇文章的时候我还没有意识到编译器版本是相关的。此语法仅在 Delphi 2010 或 XE 中可用。那里的答案不适合标记版本 Delphi 2007。Deltics 的答案涵盖了更多细节。

正如 David 的回答所暗示的那样,对于枚举类型或其他可以使用类型来限定所涉及的标识符的情况,那么您当然可以根据需要简单地使用类型名称:

someAlign  := TAlign.alNone;
someMyType := TMyType.alNone;

枚举的这种使用被称为“scoped 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,或者在标识符 不是 枚举成员并且不能通过类型限定的情况下 - 例如如果您的标识符与某些 unit 级标识符冲突(例如 mrOk,在 Controls 中),那么您需要一点点更多工作,但不多。

在这些情况下,只需定义一个新常量来为另一个单元中的常量创建一个明确的"local alias",并在单元名称明确的地方引入它。类似于:

  type
    TMyResult = (
      mrOk,
      mrFailed) ;

  const
    Controls_mrOk = Controls.mrOk;  // mrOk is a const, not an enum member