如何用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
相关产品推荐
相关产品推荐

