【问题标题】:How to get the name of a variable or object node passed by parameter in a delphi function?如何获取delphi函数中参数传递的变量或对象节点的名称?
【发布时间】:2012-07-03 08:36:53
【问题描述】:

在 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;

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

【问题讨论】:

  • 不。 if MyHierarchy.MOD_HOTSITES = 'BROWSE_ONLY'  then 怎么了?
  • 如果我没有获得许可信息,我会向自己(支持)发送一封电子邮件,告诉我 MyHierarchy.???来自用户 XXXX 的信息不完整。
  • 您可以在从数据库加载权限数据时发送电子邮件,而不是在检查您拥有的数据时发送电子邮件。然后你就有了数据库字段名称,并且可以使用它而不是尝试获取记录字段名称。
  • Java 中没有这样的 toString 方法。 Object#toString 返回对象的字符串表示形式,而不是保存该对象的变量的名称。

标签: delphi function variables parameter-passing delphi-2006


【解决方案1】:

正如 dthorpe(Delphi 的前架构师!)所说,这是不可能的。但是 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 ...

【讨论】:

    【解决方案2】:

    Delphi 不是 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;
    

    【讨论】:

    • 我不知道我们可以在 array[] 定义中使用类型。我确实不知道很多事情,我是autodidata,因为亚马逊没有德尔福专业学院......:-/
    • 任何枚举类型都可以作为索引。例如布尔值或字节。
    • 还有很多德尔福专业人士在线。他们中的一些人在docwiki.embarcadero.com 写官方文档,其他人写在个人博客(delphifeeds.com)等。
    【解决方案3】:

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

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

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

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

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

    您的IsAccessPermitted() 函数只接收记录字段内容的值。它不知道用于传递值的字段是什么,甚至根本不知道是否使用了记录

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      • 2019-04-02
      • 2012-04-05
      相关资源
      最近更新 更多