E2015 Оператор не применим к этому типу операнда (Delphi 10.2) - PullRequest
2 голосов
/ 28 июня 2019

Как и в определении интерфейса Java Collection, я хочу создать тип списка, в котором addItems / removeItems получают параметр валидатора для фильтрации элементов перед добавлением / удалением.Очень необходимый фрагмент кода:

IListItemValidator<T> = interface
  ['{79E22756-9EC5-40C5-A958-0AA04F6F1A79}']
  function validateItem( item_ : T ) : boolean;
end;

IList<T> = interface
  ['{DC051351-D7B7-48BB-984E-A0D9978A02C1}']
  function getCount : cardinal;
  function itemAt( ndx_ : cardinal ) : T;
  function addItems( list_ : ILIst<T>; validator_ : IListItemValidator<T> = NIL );
end;

TList<T> = class ( TInterfacedObject, IList<T> )
  private
    fCount : cardinal;
    fItems : TArray<T>;
  public
    function getCount : cardinal;
    function getItemAt( ndx_ : cardinal ) : T;
    function addItems( list_ : ILIst<T>; validator_ : IListItemValidator<T> = NIL );

function TList<T>.getCount : cardinal;
begin
  result := fCount;
end;

function TList<T>.getItemAt( ndx_ : cardinal ) : T;
begin
  if ( ndx_ < fCount ) then
    result := fItems[ndx_]
  else
    ;//raise...
end;

function TList<T>.addItems( list_ : ILIst<T>; validator_ : IListItemValidator<T> = NIL );
var
  i : integer;
  item : T;
begin
  if ( list_ <> NIL ) then
    for i := 0 to list_.getCount-1 do
    begin
      item := list_.getItemAt( i );
      if ( ( validator_ = NIL ) or validator_.validateItem( item ) ) then
        //addItem
      else
        result := -1;
    end
  else
    ;//raise...
end;

Как мне определить TListItemValidator, если я хочу добавить элементы со значением больше 4?(например) Анонимная функция параметризовала перегруженные методы addItems / removeItems просто отлично работает, но как я могу создать решение на основе универсального интерфейса?

Ни один вариант не компилируется:

Первый (этоясно. T не совместим с System.Integer)

TListItemValidator<T> = class ( TInterfacedObject, IListItemValidator<T> )
  public
    function validateItem( item_ : T ) : boolean;
end;

function TListItemValidator<T>.validateItem( item_ : T ) : boolean;
begin
  result := item_ > 5;
end;

Второй (я пытался использовать целое число напрямую):

TListItemValidator<integer> = class ( TInterfacedObject, IListItemValidator<integer> )
  public
    function validateItem( item_ : integer ) : boolean;
end;

function TListItemValidator<integer>.validateItem( item_ : integer ) : boolean;
begin
  result := item_ > 5;
end;

Ошибка компиляции: E2015 Operator not applicable to this operand type

Я понимаю причину: целое число в TListItemValidator точно так же, как и в первом примере T, просто заполнитель типа.Но как я могу создать работающий валидатор для целочисленных значений?

Ответы [ 2 ]

3 голосов
/ 28 июня 2019

Ваши два варианта фактически идентичны по смыслу:

TListItemValidator<T> = class ( TInterfacedObject, IListItemValidator<T> )
  public
    function validateItem( item_ : T ) : boolean;
end;

TListItemValidator<integer> = class ( TInterfacedObject, IListItemValidator<integer> )
  public
    function validateItem( item_ : integer ) : boolean;
end;

Оба они являются общими типами.Разница только в косметике, а именно в имени общего параметра.Вы могли бы дать универсальному параметру имя integer, но в данном контексте это просто имя.

Вам нужен конкретный класс, который реализует IListItemValidator<integer>.Как то так:

type
  TIntegerListItemValidator = class ( TInterfacedObject, IListItemValidator<integer> )  
    function validateItem( item_ : integer ) : boolean;
  end;

function TIntegerListItemValidator.validateItem( item_ : integer ) : boolean;
begin
  result := item_ > 4;
end;
2 голосов
/ 28 июня 2019

OK.Я нашел решение в то же время, когда Дэвид отправил свой комментарий.Я изменил определение валидатора:

IListItemValidator = interface
  [...]
  function validateItem( const item_ ) : boolean;
end;

TIntegerListItemValidator = class ( TInterfacedObject, IListItemValidator )
  function validateItem( const item_ ) : boolean;
end;

function TIntegerListItemValidator.validateItem( const item_ ) : boolean;
begin
  result := integer( item_ ) > 4;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...