【发布时间】:2020-03-04 22:30:58
【问题描述】:
我正在为旧的 Delphi XE 代码库编写一些实用程序代码;为了让事情变得更简单和更安全,我创建了一个方法来包装特定类型的TProc<TReq>(其中TReq 是泛型类类型),通过更广泛的TProc<TObject> 中的参数传递,应该提供给稍后会添加一个第三方组件,以及 TClass(TReq) 和一个额外的字符串参数:
type
TREvoHostConnectionOptions = record
// [...]
procedure OnPush<TReq:class>(const pushMethod: string; const action: TProc<TReq>);
end;
// [...]
procedure TREvoHostConnectionOptions.OnPush<TReq>(const pushMethod: string; const action: TProc<TReq>);
var
rec: TRPushHandler;
begin
rec.PushMethod := pushMethod;
rec.PushModel := TClass(TReq);
rec.Handler :=
procedure(reqRawModel: TObject)
var
reqModel: TReq;
begin
// Conversione modello richiesta
reqModel := reqRawModel as TReq;
if Assigned(reqRawModel) and not Assigned(reqModel) then
raise EEvoHostException.Create(Format('Impossibile convertire il modello di tipo %s in %s.', [reqRawModel.ClassName, TClass(TReq).ClassName]));
// Azione
if Assigned(action) then
action(reqModel);
end;
PushHandlers.Add(rec);
end;
前面的方法编译成功,如果像这样调用,会按预期工作(尽管将TObject 作为泛型类型违背了该方法的目的):
opts.OnPush<TObject>('Test', procedure (reqModel: TObject) begin (* ... *) end);
但是,如果在测试表单单元中我使用专门设计的模型类调用它:
type
TTestModel = class(TObject)
strict private
_a, _b: string;
public
property A: string read _a write _a;
property B: string read _b write _b;
end;
我在调用单元的一个完全不相关的行(以及完全不同且完全不相关的方法)中收到以下编译器错误:
[DCC 错误] WndMain.pas(96):E2010 不兼容的类型:'TTestModel' 和 'TObject'
* 如果我在同一文件中的其他任何地方引入人工语法错误,则会在正确的行报告该错误。
有什么想法吗?这是一个编译器错误,如果是,有什么办法可以解决它?不幸的是,我无法删除该方法上的 :class 约束,否则在方法内部发生的 TClass(TReq) 转换会引发(逻辑上)另一个关于 TReq 不是受约束的类或接口类型的编译错误。
【问题讨论】:
-
离题提示:尝试
Exception.Create(Format('Error %d', [123])),而不是Exception.CreateFmt('Error %d', [123])。 -
谢谢,我总是忘记 CreateFmt。 :)