Интерфейсы и Обобщения - PullRequest
2 голосов
/ 30 июля 2009

У меня проблемы с получением дженериков для работы в следующем сценарии:

Delphi предоставляет интерфейс IComparable:

IComparable <T> = interface
  function CompareTo (Value : T) : Integer;
end;

Я добавляю еще один интерфейс IPersistent:

IPersistent = interface
  function  ToString : String;
  procedure FromString (const Str : String);
end;

Один пример класса, реализующего оба интерфейса:

TComparableString = class (TInterfacedObject, IComparable <String>, IPersistent)
strict private
  FValue : String;
public
  function  CompareTo (Value : String) : Integer;
  function  ToString : String;
  procedure FromString (const Str : String);
end;

Теперь для другого универсального класса, который имеет два ограничения интерфейса:

ISortIndex <VALUE_TYPE : IPersistent, IComparable> = interface
  ...
end;

И, наконец, одна реализация этого интерфейса:

TSimpleSortIndex <VALUE_TYPE : IPersistent, IComparable> = class (TInterfacedObject, ISortIndex <VALUE_TYPE>)

  ...
end;

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

FSortIndex : ISortIndex <TComparableString>;

Я получаю сообщение об ошибке

[DCC Error] Database.pas(172): E2514 Type parameter 'VALUE_TYPE' must support  interface 'IComparable'

Я попробовал несколько вещей, но не могу заставить его работать.

Кто-нибудь нуждается в помощи? Спасибо!

1 Ответ

6 голосов
/ 30 июля 2009

Ваш класс TComparableString не реализует неуниверсальный интерфейс IComparable, поэтому он не удовлетворяет ограничению типа. Вам придется либо изменить ограничение, либо реализовать IComparable.

Изменение ограничения, вероятно, самый простой способ продвижения вперед. Я действительно не знаю Delphi, но посмотрите, работает ли это:

ISortIndex <VALUE_TYPE : IPersistent, IComparable<VALUE_TYPE>> = interface

TSimpleSortIndex <VALUE_TYPE : IPersistent, IComparable<VALUE_TYPE>> = 
    class (TInterfacedObject, ISortIndex <VALUE_TYPE>)

РЕДАКТИРОВАТЬ: я не заметил, что ваш TComparableString реализован IComparable<String> вместо IComparable<TComparableString>. Это умышленно? Обычно что-то сопоставимо с другими экземплярами самого себя, а не с другим типом.

Вы можете ввести другой параметр типа в ISortIndex / TSimpleSortIndex, чтобы указать тип, с которым VALUE_TYPE должен быть сопоставим - но я подозреваю , что более разумно изменить TComparableString.

...