2

在 Java 中,我们有类似的东西VarName.toString来识别 var 的名称。

我在 Delphi 中有一个代码,我需要实现相同的目标,因为我有一个record类型,其中包含许多需要识别的子字符串:

type
THierarchyAccess = String; // receive the user permissions from the MySQL DB
THierarchy = record
      MOD_HIERARQUIA   : THierarchyAccess; // 'BROWSE_ONLY', 'MANAGE', 'NONE'...
      MOD_OPERADORES   : THierarchyAccess;
      MOD_ESTATISTICAS : THierarchyAccess;
      MOD_AUDITORIA    : THierarchyAccess;
      MOD_HOMEPAGE     : THierarchyAccess;
      MOD_HOTSITES     : THierarchyAccess;
      MOD_MATRIZ       : THierarchyAccess;
      MOD_NOTICIAS     : THierarchyAccess;
      MOD_VISITANTES   : THierarchyAccess;
          ...
          end;
...

function  TAccess.IsAccessPermited(apNeed, apHave: String): Boolean;
begin
// HERE I need to know not only the content of "apHave", 
// but if it came from THierarchy.MOD_HOTSITES or THierarchy.MOD_MATRIZ etc.
end;

...

if IsAccessPermited('BROWSE_ONLY', MyHierarchy.MOD_HOTSITES) then Form2.Open;

有没有一种优雅的方法来识别传递给函数的变量名是什么?

4

3 回答 3

7

通常,诸如记录字段名称或参数变量名称之类的符号名称不会被 Delphi 等本地代码编译器包含在可执行映像中,因为本地机器指令只关心偏移量和地址,而不关心名称。这就是为什么 Delphi 生成的 exe 可以比同等的 .NET 或 Java 应用程序小数百倍的原因之一。

但是,字段名称等类型元数据对于“自给自足”的对象流式传输可能很有用。这种类型的元数据通常被本机代码编译器称为运行时类型信息 (RTTI)。

您可以尝试编译上面的类型,并{$M+}在类型声明周围启用。请务必在{$M-}之后立即设置,以避免使用不需要的类型名称使您的 exe 膨胀。

然后,您将需要使用 Delphi RTTI 方法来访问记录结构的字段名称。

但是,我认为这不适用于您的示例代码,因为您将记录字段作为参数传递给另一个函数。要获取记录的第 n 个字段的名称,您需要记录类型。

您的IsAccessPermitted()函数只接收记录字段内容的值。它不知道使用哪个字段来传递值,或者根本不知道是否使用了记录

于 2012-07-02T22:42:50.133 回答
4

德尔福不是Java!

您将需要使用完全不同的强类型技术。例如,您的代码可能类似于:

type
  THierarchyAccess = set of (haBrowseOnly, haManage, haNone {...});
  THierarchyMod = (hmHierarquia, hmOperadores, hmEstatisticas {...});
  THierarchy = array [THierarchyMod] of THierarchyAccess;
//...

function  TAccess.IsAccessPermited(apNeed: THierarchyAccess; apHave: THierarchy; hMod: THierarchyMod): Boolean;
begin
  case hMod of
    hmHierarquia:
      if apNeed <= apHave[hmHierarquia] then
        Beep;
    hmOperadores:
      if (apNeed + [haBrowseOnly]) <= apHave[hmOperadores] then
        Beep;
  end
end;

if IsAccessPermited([haBrowseOnly], MyHierarchy, hmOperadores) then Form2.Open;
于 2012-07-03T09:48:32.300 回答
1

正如 dthorpe(德尔福的前建筑师!)所说,这是不可能的。但是 ISTM 认为您的记录也可以是一个 THierarchyAccess 数组。

我会这样做:

type
  THierarchyMode = (mHierarchia, mOperadores, mEstatisticas, ... );

  THierarchy = array[THierarchyMode] of THierarchyAccess;

...

  procedure TAccess.IsAccessPermitted(const apNeed: THierarchyAccess; apHave: THierarchyMode; const Hierarchy: THierarchy);
  begin
    // access
    if apNeed = Hierarchy[apHave] then ...
于 2012-07-03T14:42:04.017 回答