Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi:获取调用函数的UnitName_Delphi - Fatal编程技术网

Delphi:获取调用函数的UnitName

Delphi:获取调用函数的UnitName,delphi,Delphi,在我的程序中有很多地方我称之为字典(…)。如何避免将UnitName作为第二个参数传递? 是否可以在MyTranslateUnit中获取调用方的UnitName而无需第二个参数 我想要一个函数,比如 函数字典(sTextToTranslate:string) 只要调用发生在类的方法内部,就可以简单地编写UnitName。每个DelphiTObject都提供了类函数UnitName:string,它给出类声明所在的单元的名称 这不会让您忽略第二个参数,但它简化了重命名单元或在单元之间复制或移动代码

在我的程序中有很多地方我称之为字典(…)。如何避免将UnitName作为第二个参数传递?
是否可以在MyTranslateUnit中获取调用方的UnitName而无需第二个参数

我想要一个函数,比如

函数字典(sTextToTranslate:string)


只要调用发生在类的方法内部,就可以简单地编写
UnitName
。每个Delphi
TObject
都提供了
类函数UnitName:string,它给出类声明所在的单元的名称

这不会让您忽略第二个参数,但它简化了重命名单元或在单元之间复制或移动代码时的维护

Edit:在没有第二个参数的情况下,有一个真正的肮脏的黑客可以使它工作,而且它也只能在类的方法中工作。我建议利用这个作为最后的手段!删除一个参数的好处将来很容易适得其反

为ToObject声明一个类帮助器,如下所示:

unit MyTranslateUnit;
  function Dictionary(sTextToTranslate: string; sUnitName: string)
  begin
    // Here I need the UnitName of the caller
    Result := ...
  end;
end.
现在你可以称之为

type
  TRealDirtyDontDoItObjectHelper = class helper for TObject
  public
    class function Dictionary(const sTextToTranslate: string): string;
  end;

implementation

class function TRealDirtyDontDoItObjectHelper.Dictionary(const sTextToTranslate: string): string;
begin
  { whatever implementation should go here }
  Result := UnitName + ': ' + sTextToTranslate;
end;
在任何方法中,
UnitName
给出了该方法所属类声明的单元。请注意,这意味着当前实例的类,而不一定是声明方法的某个继承类


我还应该提到,TObject的这个类助手不会干扰任何其他类的类助手,即使这些类显然继承自
TObject

是否有类似于“parent.UnitName”的内容,或者每次调用Dictionary()时都必须编写第二个参数?此解决方案报告正在调用的类方法的实现
UnitName
,而不是调用该方法的任何代码的
UnitName
,该方法很容易位于另一个单元中。因此,我对此投了反对票,因为它没有解决被问到的实际问题:“是否有可能获取调用方的UnitName…”@RemyLebeau,它报告调用字典的单元的名称,而不是声明类方法字典的单元。根据Delphi 10.2.2进行测试。我很想得到你反对的证据。@Uwerabe:我试过你提供的代码。助手报告的
UnitName
是调用该助手的对象的单位。只有当调用方是通过调用方自己的
Self
指针调用助手的类方法时,它才是调用方的单位。也许这就是你想要的。但是在其他对象上调用辅助对象,会得到不同的结果。除非通过类类型调用,否则不能从非类过程调用helper,但这样就得到了该类的单位。不是来电者的单位。所以这仍然不是一个非常灵活的解决方案。@RemyLebeau,事实上,这不仅是我想要的,也是我写的。调用的示例没有显示故意调用someobject.Dictionary。无论如何,我承认你不喜欢这个解决方案,我也不喜欢。简单的回答是Delphi并不支持你的要求。但是,也有第三方解决方案(特别是第三方堆栈跟踪器)。它通常涉及为项目生成
.map
.tds
文件,并将其与应用程序一起部署(如果不是静态链接),然后让函数检索它自己的
ReturnAddress
,并将其与
.map
/
.tds
文件中的特定条目相匹配,以确定调用方的名称以及实现它的单元。您可能希望这样做是为了调试,否则您的设计就很糟糕(不管你会想出什么借口)。所以,回到调试上来……你正在以一种笨拙、狭隘和迂回的方式处理这个问题。你最好研究一下堆栈跟踪的概念。有很多调试工具可以帮助你做到这一点:*异常的魔力;*疯狂的例外;*Jcl调试。举几个例子。
unit MyTranslateUnit;
  function Dictionary(sTextToTranslate: string; sUnitName: string)
  begin
    // Here I need the UnitName of the caller
    Result := ...
  end;
end.
type
  TRealDirtyDontDoItObjectHelper = class helper for TObject
  public
    class function Dictionary(const sTextToTranslate: string): string;
  end;

implementation

class function TRealDirtyDontDoItObjectHelper.Dictionary(const sTextToTranslate: string): string;
begin
  { whatever implementation should go here }
  Result := UnitName + ': ' + sTextToTranslate;
end;
Caption := Dictionary('title');