Я пишу некоторый служебный код для старой кодовой базы 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
не является ограниченным классом или типом интерфейса.