CnPack Forum » 技术板块灌水区 » 匿名过程转换成事件过程的意义和方法


2011-1-5 00:14 zzzl
匿名过程转换成事件过程的意义和方法

先贴一小段例子说明这个方法的意义

[color=#000080][b]procedure[/b][/color] [color=#000000]TForm1.[/color][color=#000000]Button1Click[/color]([color=#000000]Sender[/color][color=#000000]:[/color] [color=#000080][b]TObject[/b][/color]);
[color=#000080][b]var[/b][/color]
    s[color=#000000]:[/color] [color=#000080][b]string[/b][/color];
[color=#000080][b]begin[/b][/color]
s[color=#000000]:=[/color][color=#0000ff]'aa'[/color]; [color=darkgreen]//用这句表示s的值经过一个复杂的计算,得出值为aa[/color]
[color=darkgreen]
[/color][color=#000000]timer1[/color][color=#000000].[/color][color=#000000]OnTimer[/color][color=#000000]:=[/color][color=#000000]NotifyEvent[/color](  [color=#006400]//给这个TTimer控件指定onTimer事件[/color]
    [color=#000080][b]procedure[/b][/color]([color=#000000]sender[/color][color=#000000]:[/color] [color=#000080][b]TObject[/b][/color])
    [color=#000080][b]begin[/b][/color]
    [color=#000000]memo1[/color][color=#000000].[/color][color=#000000]Lines[/color][color=#000000].[/color][color=#000000]Add[/color](s[color=#000000]+[/color]  [color=#000000]sender[/color][color=#000000].[/color][color=#000000]ToString[/color]);  [color=#006400]//这里使用了s变量,是的,它能“看见”s[/color]
    [color=#000080][b]end[/b][/color]);
[color=#000080][b]end[/b][/color];

如果用别的方法实现上面的功能,s可能会被放在TForm1宝贵的private区域,以让OnTimer事件函数能看到它。而这个方法使你可以连贯的表达你的意图:计算s的值,以某种方式显示它。你不必把这个整体的逻辑划分到两个函数里。


有很多个理由需要把一个匿名过程转换成事件类型,但delphi似乎没有直接提供这个方法,如果有谁知道的话记得告诉我。


//////////////////////////////////////////////////////////////////////////////////////////////////////////////

我自己的实现方法很简单,也很笨,代码很短,贴出来了

[color=#000000]_CPack[/color][color=#000000]=[/color][color=#000080][b]class[/b][/color]([color=#000000]TComponent[/color])  [color=#006400]//这个类不应被客户端看到,它只为NotifyEvent函数使用,所以我在前面加了个下划线。[/color]
[color=#000080][b]private[/b][/color]
    [color=#000000]fProc[/color][color=#000000]:[/color] [color=#000000]TProc[/color][color=#000000]<[/color][color=#000080][b]TObject[/b][/color][color=#000000]>;[/color]
    [color=#000080][b]procedure[/b][/color] [color=#000000]event[/color]([color=#000000]sender[/color][color=#000000]:[/color] [color=#000080][b]TObject[/b][/color]);
[color=#000080][b]end[/b][/color];

[color=#000080][b]procedure[/b][/color] [color=#000000]_CPack[/color][color=#000000].[/color][color=#000000]event[/color]([color=#000000]sender[/color][color=#000000]:[/color] [color=#000080][b]TObject[/b][/color]);
[color=#000080][b]begin[/b][/color]
[color=#000000]fProc[/color]([color=#000000]sender[/color]);
[color=#000080][b]end[/b][/color];

[color=#000080][b]function[/b][/color] [color=#000000]NotifyEvent[/color](p[color=#000000]:[/color] [color=#000000]TProc[/color][color=#000000]<[/color][color=#000080][b]TObject[/b][/color][color=#000000]>[/color])[color=#000000]:[/color] [color=#000000]TNotifyEvent[/color];
[color=#000080][b]var[/b][/color]
    [color=#000000]obj[/color][color=#000000]:[/color] [color=#000000]_CPack[/color];
[color=#000080][b]begin[/b][/color]
[color=#000000]obj[/color][color=#000000]:=[/color][color=#000000]_CPack[/color][color=#000000].[/color][color=#000000]Create[/color]([color=#000000]Application[/color]);
[color=#000000]obj[/color][color=#000000].[/color][color=#000000]fProc[/color][color=#000000]:=[/color]p;
[color=#000000]Result[/color][color=#000000]:=[/color][color=#000000]obj[/color][color=#000000].[/color][color=#000000]event[/color];
[color=#000080][b]end[/b][/color];

这个实现方法的缺点是每调用一次[color=#000000]NotifyEvent都要产生一个[color=#000000]TComponent[/color][color=#000000]对象,不过[color=#000000]NotifyEvent的调用次数应该是在编译时确定的,所以数量微不足道,如果要在运行时确定,你可以将NotifyEvent的返回值暂存起来用。[/color][/color][/color]
[color=#000000][color=#000000][/color][/color]
[color=#000000][color=#000000][color=#000000][color=#000000][color=#000000]这个缺点对我来说不成问题,因为我在写客户端程序时倾向于不释放资源以换取稳定性。[/color][/color]
[color=#000000][/color]
[color=#000000][color=#000000]如果你实在在意这个leak,可以给NotifyEvent加一个out id参数,有了id,你就可以控制生存期了。[/color][/color]
[color=#000000][/color][color=#000000][/color]
[color=#000000][/color]
[color=#000000][color=#000000]另一个实现在这里([url=http://kindi.tistory.com/entry/Using-anonymous-methods-in-method-pointers]http://kindi.tistory.com/entry/Using-anonymous-methods-in-method-pointers[/url])[/color][/color][/color][/color][/color],韩语的,不知在说什么,但我把它的代码拷出来,上面的示例可以编译通过,也没有我上面方法的问题,但唯一的问题是,它输出的结果是“Timer1”,而不是“aaTimer1",换句话说,s的值不见了。

2011-8-18 10:26 friendlinzh
procedure event(sender: TObject);

页: [1]


Powered by Discuz! Archiver 5.0.0  © 2001-2006 Comsenz Inc.