GOOGLE ADS

суббота, 30 апреля 2022 г.

Несовместимость типа интерфейса Delphi

Что я пытаюсь сделать, так это добавить общие методы к этим двум классам, которые имеют одного и того же косвенного предка.

IMyMethods = interface
procedure SomeMethod;
end;
TMyADODataset =class(TADODataset, IMyMethods) // ADO
public
procedure SomeMethod;
end;
TMyUniDataset =class(TUniTable, IMyMethods) // UniDAC
public
procedure SomeMethod;
end;

SomeMethodбудут реализованы по-разному для ADO и для UniDAC. Поэтому я подумал, что интерфейс идеален.

Тогда у нас есть

TMyTable =class
private
FDataset: TDataset;
end;

Здесь я выбрал TDataset, поскольку он является общим предком TADODataset и TUniTable.

FDataset может быть создан следующим образом:

if FProvider = prADO then
FDataset:= TMyADODataset.Create
else
FDataset:= TMyUniDataset.Create;

Теперь проблема в том, как вызвать SomeMethod, FDatasetследующее не компилируется и выдает ошибку несовместимости типов:

IMyMethods(FDataset).SomeMethod;

Это потому TDataset, что не реализует IMyMethods, что правильно. Но есть ли способ заставить компилятор принять это? Или есть лучшее решение? Я думал о помощниках классов, но их реализация SomeMethodбудет отличаться для ADO и UniDAC.


Решение проблемы

Используйте SysUtils.Supports()функцию для получения IMyMethodsинтерфейса от FDatasetобъекта, например:

uses
..., SysUtils;
var
Intf: IMyMethods;
...
if Supports(FDataset, IMyMethods, Intf) then
Intf.SomeMethod;

Просто обратите внимание, что для того, чтобы это работало, IMyMethodsему должен быть назначен Guid, например:

type
IMyMethods = interface
['{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}']
procedure SomeMethod;
end;

Вы можете сгенерировать новый Guid прямо в редакторе кода, нажав Ctrl+Shift+G.

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...