为什么我的D10和D12均不支持匿名方法?

秋天之落叶 2025-05-16 10:45:51

procedure TForm5.Button2Click(Sender: TObject);
var
  Timer: TTimer;
  PosX: Integer;
  lblMessage: TLabel;
begin
  PosX := 0;
  lblMessage := TLabel.Create(Self);
  lblMessage.Parent := Self;
  lblMessage.Caption := 'Moving Text';

  Timer := TTimer.Create(nil);
  Timer.Interval := 50;
  Timer.OnTimer := procedure(Sender: TObject)
    begin
      PosX := PosX + 2;
      lblMessage.Left := PosX;
    end;                    //这里提示错误E2010 Incompatible types: 'TNotifyEvent' and 'Procedure'的错误

  // 。。。

end;

--------提示错误E2010 Incompatible types: 'TNotifyEvent' and 'Procedure'的错误

================================

但我新建项目测试时可以通过的:

procedure TForm5.Button1Click(Sender: TObject);
var
  proc: TProc;
begin
  proc := procedure
    begin
      ShowMessage('匿名方法测试成功!');
    end;
  proc(); // 执行匿名方法

end;

有知道的大佬指点一二!

 

...全文
206 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

是可以的:

procedure TForm1.Button2Click(Sender: TObject);
type
  TNotifyEventRef = reference to procedure(Sender: TObject);
  TVMT = array[0..3] of pointer;
  PVMT = ^TVMT;
var
  R: TNotifyEventRef;
  P: ^PVMT absolute R;
  M: TMethod;
  n: integer;
begin
  R := procedure(Sender: TObject)
       begin
         Memo1.Lines.Add(n.ToString);
         Dec(n);
         if n < 1 then Timer1.Enabled := false;
       end;
  M.Code := P^^[3];
  M.Data := P;

  n := 10;
  Timer1.OnTimer := TNotifyEvent(M);
  Timer1.Enabled := true;
end;
  • 举报
回复
@日立奔腾浪潮微软松下联想 测试结果和我的一样,连续弹出错误框,一直不停
@秋天之落叶 编译成64位是可以的,32位出现异常,我再看看。
@秋天之落叶 就是因为R在Button2Click结束时被释放了造成的,32位和64位编译器的释放机制似乎有点不一样,把R改成全局变量就好了。当然如果匿名函数内部没有捕获外部变量就无所谓,代码本身是不会被释放的。
3条回复
  • 打赏
  • 举报
回复

因为事件是方法指针(隐含的TMethod),不是普通的函数指针或者方法引用,而匿名函数是方法引用。
技术上是可以转换方法引用到方法指针的,但是存在一定风险,因为方法引用是带引用计数的,超出使用它的作用域之后会被释放掉,此后再触发事件会出现运行时问题(如果匿名函数中捕获了外部变量就会很严重)。

  • 举报
回复
@日立奔腾浪潮微软松下联想 但是我用TMethod也不行,运行连续报错: var MyProc: TNotifyEvent; Method: TMethod; begin Method.Code := @procedure(Sender: TObject) begin // 代码 end; Method.Data := nil; TMethod(MyProc) := Method; // 使用TMethod进行类型断言 Timer.OnTimer := MyProc; end;
  • 打赏
  • 举报
回复

奇怪,我使用函数就可以:
procedure TForm2.Button1Click(Sender: TObject);
begin
ShowMessageFmt('x + y = %d', [Calc(10, 15,
function(x, y: Integer): Integer
begin
Result := x + y;
end)]);
end;

5,927

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧