delphi – 在pascal中动态分配匿名通用函数
发布时间:2020-12-15 09:23:06 所属栏目:大数据 来源:网络整理
导读:我有以下类层次结构 我希望能够动态地分配对TB和TC两种类型的对象进行操作的匿名方法. 所以这是一个简单的人为例子: unit Unit1;interfaceuses Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,
我有以下类层次结构
我希望能够动态地分配对TB和TC两种类型的对象进行操作的匿名方法. 所以这是一个简单的人为例子: unit Unit1; interface uses Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; TNotifyEventWrapper = class private FProc: TProc<TObject>; public constructor Create(Proc: TProc<TObject>); published procedure Event(Sender: TObject); end; IA = interface procedure Foo; end; TA = class(TInterfacedObject) procedure Foo; end; TB = class(TA,IA) procedure Foo; end; TC = class(TA,IA) procedure Foo; end; TControl = class strict private public class var NEW : TNotifyEventWrapper; class var Foo : TNotifyEvent; class function GetWrapper<T:TA,IA,constructor>(D: T): TNotifyEventWrapper; class procedure AssignFooHandler<T:TA,constructor>; end; var Form1: TForm1; implementation {$R *.dfm} procedure TC.Foo; begin ShowMessage('TC.Foo'); end; class function TControl.GetWrapper<T>(D: T): TNotifyEventWrapper; begin Result := TNotifyEventWrapper.Create ( procedure (S : TObject) begin T(D).Foo; end ); end; class procedure TControl.AssignFooHandler<T>; var X : T; begin X := T.Create; try TControl.NEW := TControl.GetWrapper<T>(X); TControl.Foo := TControl.NEW.Event; finally FreeAndNil(X); end; end; procedure TA.Foo; begin ShowMessage('TA.Foo'); end; procedure TB.Foo; begin ShowMessage('TB.Foo'); end; constructor TNotifyEventWrapper.Create(Proc: TProc<TObject>); begin inherited Create; FProc := Proc; end; procedure TNotifyEventWrapper.Event(Sender: TObject); begin FProc(Sender); end; procedure TForm1.Button1Click(Sender: TObject); begin TControl.Foo(Sender); end; procedure TForm1.Button2Click(Sender: TObject); begin TControl.AssignFooHandler<TC>; //TB end; end. 我想能打电话 TControl.AssignFooHandler< TC取代; 并拥有TControl.Foo(发件人);方法调用TC.Foo 我也想要TControl.AssignFooHandler< TB> ;;导致TControl.Foo(发件人);调用TB.Foo 不幸的是,当我运行它时,它总是调用基类方法TA.Foo. 我不知道怎么解决这个问题. 解决方法
您的Generic被限制为TA和IA的后代. TA.Foo未声明为虚拟,而T(B | C).Foo()未声明为覆盖它.这就是每次调用TA.Foo()的原因.你需要使TA.Foo()虚拟和T(B | C).Foo覆盖它,然后T(B / C).Foo将按预期调用.
此外,在TControl.Foo()有机会调用该对象的Foo()方法之前,您正在释放传递给TControl.GetWrapper()的T(A / B / C)对象.在这个特定的例子中,没关系,因为没有一个Foo()方法访问任何对象成员字段,但是一旦你在实际的生产代码中开始这样做,它很可能会崩溃.在完成使用TNotifyEventWrapper对象之前,需要保持T(A / B / C)对象处于活动状态. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |