以类型安全的方式将方法的代码作为参数传递 [英] Passing a method's code as an argument in a typesafe way

查看:26
本文介绍了以类型安全的方式将方法的代码作为参数传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将方法作为参数传递不是问题:

Passing a method as an argument is not a problem:

type
  TSomething = class
    Msg: string;
    procedure Show;
  end;

procedure TSomething.Show;
begin
  ShowMessage(Msg);
end;

type TProc = procedure of object;

procedure Test(Proc: TProc);
begin
  Proc;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Smth: TSomething;

begin
  Smth:= TSomething.Create;
  Smth.Msg:= 'Hello';
  Test(Smth.Show);
end;

我需要一些棘手的事情 - 只传递方法的代码部分.我知道我可以做到:

I need something tricky - to pass only a code part of a method. I know I can do it:

procedure Test2(Code: Pointer);
var
  Smth: TSomething;
  Meth: TMethod;

begin
  Smth:= TSomething.Create;
  Smth.Msg:= 'Hello Hack';
  Meth.Data:= Smth;
  Meth.Code:= Code;
  TProc(Meth);
  Smth.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Test2(@TSomething.Show);
end;

但这是一个黑客和不安全的 - 编译器无法检查方法的参数.

but that is a hack and unsafe - the compiler can't check the method's arguments.

问题:是否可以以类型安全的方式做同样的事情?

The question: Is it possible to do the same in a typesafe way?

推荐答案

我终于明白了.带类型检查,无需为调用事件声明变量!

I got it finally. With type checking and no need to declare variable for the calling event!

type

  TSomething = class
    Msg: string;
    procedure Show;
    procedure ShowWithHeader(Header : String);
  end;

  TProc = procedure of object;
  TStringMethod = procedure(S : String) of Object;

procedure TSomething.Show;
begin
  ShowMessage(Msg);
end;

procedure TSomething.ShowWithHeader(Header: String);
begin
  ShowMessage(Header + ' : ' + Msg);
end;

procedure Test2(Code: TProc);
var
  Smth: TSomething;
begin
  Smth:= TSomething.Create;
  Smth.Msg:= 'Hello Hack 2';
  TMethod(Code).Data := Smth;
  Code;
  Smth.Free;
end;

procedure Test3(Code: TStringMethod; S : String);
var
  Smth: TSomething;
begin
  Smth:= TSomething.Create;
  Smth.Msg:= 'Hello Hack 3';
  TMethod(Code).Data := Smth;
  Code(S);
  Smth.Free;
end;

procedure TForm4.btn1Click(Sender: TObject);
begin
  Test2(TSomething(nil).Show);
//  Test2(TSomething(nil).ShowWithHeader); // Cannot Compile
end;

procedure TForm4.btn2Click(Sender: TObject);
begin
//  Test3(TSomething(nil).Show,'Hack Header');  // Cannot Compile
  Test3(TSomething(nil).ShowWithHeader,'Hack Header');
end;

这篇关于以类型安全的方式将方法的代码作为参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆