Delphi 2009 無名メソッド・匿名関数 (Anonymouse Method) - Delphi 2009
Delphi 2009でサポートされた無名メソッド(匿名メソッド)を使ってみます。
まず、フォームにボタンを1つ配置して下記のコードを書きます。
実行して、ボタンを押すとビープが鳴ります。シンプルです。
あまり意味がないような気もします・・・。
次に、別のボタンを配置し、下記のコードを記述します。
実行し、ボタンを押すと下図の実行結果が得られます。
なんか、怪しげな挙動をします。GetFunctionで与えた引数が保持された形で、関数ポインタが返されるようです。クラスを定義してメンバ変数に値を入れるような処理が簡単に記述できます。(処理が追いかけにくいので、可読性は落ちるような気もしますが・・・)
さらに、下記のコード記述してみました。
ボタンを配置し、ボタンのイベントといくつかのメソッドを実装
クラス定義部に、TThreadを派生させたスレッドクラスTMyThreadを定義
派生スレッドクラスTMyThreadの実装
このプログラムを実行し、Button3を押すと下図の実行結果が得られます。
手続き的にマルチスレッドプログラムを記述することができます。
便利かもしれません
プログラム全体
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
Tproc= reference to procedure;
TMyFunc = reference to function(input:string):string;
TMyThread = class(TThread)
public
Name:string;
Proc:Tproc;
procedure execute; override;
end;
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
function GetFunction(init:string):TMyFunc;
{ Private 宣言 }
public
procedure ExecFor(proc:Tproc;Name:string);
procedure ThreadTerminate(Sender:TObject);
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TMyThread.execute;
begin
inherited;
Proc;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
f: Tproc;
begin
f:=procedure
begin
beep;
end;
f;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
f:TMyFunc;
begin
f:=GetFunction('Phase1:');
Memo1.Lines.Add(f('wait'));
Memo1.Lines.Add(f('wait..'));
Memo1.Lines.Add(f('wait....'));
Memo1.Lines.Add(f('OK! Complete'));
f:=GetFunction('Phase2');
Memo1.Lines.Add(f('wait'));
Memo1.Lines.Add(f('wait..'));
Memo1.Lines.Add(f('wait....'));
Memo1.Lines.Add(f('OK! Complete'));
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
ExecFor(procedure
begin
sleep(12000);
end,'スレッド1'
);
ExecFor(procedure
begin
sleep(5000);
end,'スレッド2'
);
ExecFor(procedure
begin
sleep(7000);
end,'スレッドだばー'
);
end;
procedure Tform1.ExecFor(proc:Tproc;Name:string);
var
mt:TMyThread;
begin
mt:=TMyThread.Create(true);
mt.Proc:=proc;
mt.Name:=Name;
mt.OnTerminate:=form1.ThreadTerminate;
mt.Resume;
end;
procedure Tform1.ThreadTerminate(Sender:TObject);
begin
Memo1.Lines.Add(TMyThread(Sender).Name+ 'Terminated');
end;
function TForm1.GetFunction(init:string):TMyFunc;
begin
result:=function (input:string):string
begin
result:=init+input;
end;
end;
end.
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用