delphi - 使用 RTTI 方法调用返回的函数引用

标签 delphi rtti delphi-10.2-tokyo

在 Delphi 程序中,具有以下模式:

TDelegate=reference to procedure(const Arg: TMyType); 

TRouter = class
  ...
public
  procedure RegisterHandler(const route: string: handler: TDelegate);
end;

THandlerContainer = class
public
  function getDelegate: TDelegate;
  procedure register(const Router: TRouter);
end; // class

...
procedure THandlerContainer.register(const router: TRouter)
begin
  router.RegisterHandler('route', getDelegate);
end;

基本上,我正在注册用于处理一些消息处理的函数引用(基于“route”字符串)。

我想为我的同事简化模式,这样他们就不必为每个实现调用 router.RegisterHandler 自己,而只需向他们的类添加一个属性,然后将一个实例传递给 TRouter 的方法,该方法将使用RTTI查找所有由该属性修饰的方法并注册它们。

因此,我为该装饰创建了一个简单的属性RegisterMessageHandlerAttribute(使用自定义构造函数来接收路由字符串),并编写了一个 TRouter 方法,该方法使用 RTTI 来查找用该属性装饰的所有方法:

function TRouter.RegisterHandlers(const HandlerContainerClass:
    TObject);
var
  RTTIContext: TRttiContext;
  RttiType : TRttiType;
  prop: TRttiMethod;
  Attr: TCustomAttribute;
begin
  RTTIContext := TRttiContext.Create;
  try
    RttiType := RTTIContext.GetType(HandlerContainerClass);
    if assigned(RttiType) then
    begin
      for prop in RttiType.GetMethods do
      begin
         for Attr in Prop.GetAttributes do
         begin
           if (Attr is RegisterMessageHandlerAttribute) then
           begin
               Self.RegisterHandler(
                (Attr as RegisterMessageHandlerAttribute).Route,
                TDelegate(Prop.Invoke(HandlerContainerClass, []).AsPointer); // <--- this fails
               );
           end;
         end;
      end;
    end;
  finally
    RTTIContext.Free;
  end;
  result := Handlers.ToArray;
end;

不幸的是,编译器在我通过调用方法检索 lambda 的行上提示:

TDelegate(Prop.Invoke(HandlerContainerClass, []).AsPointer);
...
[dcc32 Error] GIT.MessageQueue.Router.pas(169): E2089 Invalid typecast

我的问题是我不知道如何获取 Prop.Invoke 返回的 TValue 类型并将其用作 TDelegate 类型的函数引用。

最佳答案

只需使用 .AsType<TDelegate>() - 这将返回 TValue 的内容如TDelegate 。该功能还确保您不会转动 TValue 内的内容。变成不明确赋值兼容的东西(不像变体那样)。但由于这是您的函数的确切返回类型,因此它将正常工作。

附注您需要显式键入括号,否则编译器可能会出现 E2010 错误。

关于delphi - 使用 RTTI 方法调用返回的函数引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53391484/

相关文章:

Delphi使用内置工具本地化VCL程序

delphi - 是否有一种无需尝试就可以有效地对程序进行防弹的方法?

sql-server - 跨不同 SQL 数据库兼容的 DDL(CREATE TABLE)?

delphi - 如何将一个类实例的属性复制到同一类的另一个实例?

json - Swift 中的安全动态 JSON 转换

delphi - 调试包含字符串的 TValue

delphi - 为什么 memo.Lines 使用 TStrings 而不是 TStringList?

database - 能否通过 DBGrids 更新复杂查询?

c++ - 显式调用基本复制构造函数 => RTTI 信息丢失。漏洞?

android - Delphi Android 应用程序 API 级别 26?