You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Delphi泛型统一接收可调用对象(过程、方法、Lambda)

用Delphi泛型模拟C++可调用对象,消除重载代码重复

完全可以借助Delphi泛型结合匿名委托特性,实现统一的可调用对象处理,彻底消除重复的重载实现。以下是具体的实现思路和代码示例:

核心思路

Delphi中,普通过程、类方法、Lambda表达式本质上都可以通过泛型委托类型进行统一抽象。其中Lambda本身就是匿名方法,普通过程和类方法可以直接适配到预定义的泛型委托(如TProc/TFunc),最终用单一泛型过程接收统一类型的参数,无需重复重载。

具体实现方案

方案1:直接使用预定义泛型委托

Delphi自带System.SysUtils中的TProc(无返回值)和TFunc(有返回值)系列泛型类型,直接用它们作为参数类型,即可兼容所有可调用对象:

uses System.SysUtils;

// 无参数无返回值的统一调用过程
procedure ExecuteCallable(const ACallable: TProc);
begin
  ACallable();
end;

// 带单个参数的泛型版本(可按需扩展多参数)
procedure ExecuteCallable<T>(const ACallable: TProc<T>; const AParam: T);
begin
  ACallable(AParam);
end;

// 带返回值的版本(用TFunc)
function ExecuteCallable<TResult>(const ACallable: TFunc<TResult>): TResult;
begin
  Result := ACallable();
end;

调用示例:

// 普通过程
procedure NormalProc;
begin
  Writeln('普通过程');
end;

// 类方法
type
  TTestClass = class
    class procedure ClassMethod(Value: Integer);
  end;

class procedure TTestClass.ClassMethod(Value: Integer);
begin
  Writeln('类方法,参数:', Value);
end;

// 主程序入口
var
  LambdaWithResult: TFunc<String>;
begin
  // 调用普通过程
  ExecuteCallable(NormalProc);
  // 调用类方法
  ExecuteCallable<Integer>(TTestClass.ClassMethod, 123);
  // 内联Lambda
  ExecuteCallable(procedure
    begin
      Writeln('内联Lambda');
    end);
  // 带返回值的Lambda
  LambdaWithResult := function: String
    begin
      Result := 'Lambda返回值';
    end;
  Writeln(ExecuteCallable<String>(LambdaWithResult));
end;

方案2:自定义泛型包装类(复杂场景扩展)

如果需要更灵活的可调用对象管理(比如绑定状态、自定义参数组合),可以自定义泛型类封装:

type
  TCallableWrapper<TInput, TResult> = class
  private
    FFunc: TFunc<TInput, TResult>;
  public
    constructor Create(const AFunc: TFunc<TInput, TResult>);
    function Execute(const AInput: TInput): TResult;
  end;

constructor TCallableWrapper<TInput, TResult>.Create(const AFunc: TFunc<TInput, TResult>);
begin
  inherited Create;
  FFunc := AFunc;
end;

function TCallableWrapper<TInput, TResult>.Execute(const AInput: TInput): TResult;
begin
  Result := FFunc(AInput);
end;

// 使用示例
procedure TestCustomWrapper;
var
  Wrapper: TCallableWrapper<Integer, String>;
begin
  Wrapper := TCallableWrapper<Integer, String>.Create(
    function(Value: Integer): String
    begin
      Result := Format('转换后的值:%d', [Value * 2]);
    end
  );
  try
    Writeln(Wrapper.Execute(5));
  finally
    Wrapper.Free;
  end;
end;

关键说明

  • Delphi的匿名方法(Lambda)是闭包类型,天然支持适配普通过程、类方法、对象方法,无需额外RTTI处理(私有方法场景除外)。
  • 泛型参数可根据业务需求自由扩展,比如TProc<T1, T2, T3>支持多参数,TFunc<T1, TResult>支持输入参数+返回值,完全覆盖C++可调用对象的使用场景。
  • 这种方式彻底替代了多份重载代码,所有可调用类型都通过统一的泛型委托传递,代码复用性大幅提升。

内容的提问来源于stack exchange,提问作者jpo234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 23:15:35