传递方法的code作为参数的类型安全方式

传递方法的code作为参数的类型安全方式

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

问题描述

传递的方法作为参数是没有问题的:

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;

我需要一些棘手的 - 只传递一个方法的code的一部分。我知道我能做到这一点:

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;

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

08-12 16:07