我想为ITask / TTask添加一些功能。我将新方法包装在一个继承自ITask的新接口(IMyTask)中:
type
IMyTask = interface(ITask)
procedure MyNewMethod;
end;
TMyTask = class(TTask, ITask, IMyTask)
private
FSomeList: TList<integer>;
public
procedure MyNewMethod;
constructor Create(const AProc: TProc; AThreadPool: TThreadPool = nil); overload;
constructor Create(Sender: TObject; Event: TNotifyEvent); overload;
constructor Create(const Proc: TProc); overload;
constructor Create(Sender: TObject; Event: TNotifyEvent; const APool: TThreadPool); overload;
end;
我的类包含应在其构造函数中初始化的成员(例如FSomeList)。所以调用我的构造函数是强制性的。同时我不想改变Create()的实现。所以我将Create()声明为具有四个覆盖的构造函数。 但是创建TMyTask的实例无法使用E2251进行编译:
procedure TestCreateMyTask;
var
i: IMyTask;
begin
i := TMyTask.Create( // --> E2251 Ambiguous overloaded call to 'Create'
procedure
begin
end
);
end;
我尝试使用“重新引入”关键字,但似乎无法工作可能是因为所有Create()方法都标有“重载”。
如何克服这个问题?
更新
进一步测试产生了两个QC:
答案 0 :(得分:2)
为什么你觉得你应该创建一个TTask后代?除非在极少数情况下,否则不应创建TTask后代。更好的解决方案是在另一个对象中使用常规任务。
TTask上的Create方法实际上不是构造函数,而是静态类函数。这样做的原因是确保您只使用ITask而不是TTask。您也无法使用默认的无参数构造函数构造TTask(它引发异常)。源甚至在该构造函数附近有注释
constructor Create; overload; // do not call this constructor!!
“创建”功能和“运行”功能之间的区别在于是否安排了任务。运行将返回已安排到线程池中的任务。创建将推迟到调用者决定安排它时。
class function Create(Sender: TObject; Event: TNotifyEvent): ITask; overload; static; inline;
class function Create(const Proc: TProc): ITask; overload; static; inline;
class function Create(Sender: TObject; Event: TNotifyEvent; const APool: TThreadPool): ITask; overload; static; inline;
class function Create(const Proc: TProc; APool: TThreadPool): ITask; overload; static; inline;
class function Run(Sender: TObject; Event: TNotifyEvent): ITask; overload; static; inline;
class function Run(Sender: TObject; Event: TNotifyEvent; APool: TThreadPool): ITask; overload; static; inline;
class function Run(const Func: TProc): ITask; overload; static; inline;
class function Run(const Func: TProc; APool: TThreadPool): ITask; overload; static; inline;
正如我所说,最好直接使用TTask Create或Run方法而不是创建后代。如果要封装任务的操作,请随意创建自己的类类型,并在内部创建和安排任务。