Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Создание generic коллекции в Delphi XE2 для работы с объектами, имеющими метод Copy(ownType)

Delphi , Компоненты и Классы , Коллекции

В статье описывается проблема создания generic коллекции в Delphi XE2 для работы с объектами, имеющими метод Copy(ownType). Автор хочет создать коллекцию, которая может манипулировать объектами, имеющими метод Copy, но не может понять, как лучше всего объявить это.

В качестве примера автор приводит простую коллекцию из одного элемента:

//------ Library ------
Type
  TBaseCopyable = class
    S: string;
    procedure Copy(OtherObject: TBaseCopyable); virtual;
  end;

  MyCollection<T: TBaseCopyable, constructor> = class
    TheItem: T;
    procedure SetItem(AItem: T);
    function  GetItem: T;
  end;

//------ Usage ------
Type
  TMyCopyable = class(TBaseCopyable)
    I: integer;
    procedure Copy(OtherObject: TMyCopyable); override;
  end;

[...]
  Col: MyCollection<TMyCopyable>;

Проблема в том, что в Col автор хочет, чтобы generic реализация MyCollection нашла TMyCopyable.Copy, но ни перегрузка, ни виртуальный метод не работают. С перегрузкой код компилируется, но MyCollection.GetItem находит TBaseCopyable.Copy, а не TMyCopyable.Copy. С виртуальным/переопределением не компилируется, так как сигнатуры двух Copy declarations не совпадают.

Автор предполагает, что ему нужно использовать generics somehow в спецификации TBaseCopyable, возможно вместо наследования, но не уверен, как это сделать, так как он не особо нуждается в передаче параметра типа в TBaseCopyable, ему просто нужно, чтобы Copy аргумент типа ссылался на "тип своего класса" generic образом.

В качестве альтернативного ответа автор предлагает сделать TBaseCopyable generic классом и применить его generic тип к Copy(), тогда TMyCopyable сможет переопределить его. Альтернативой может быть то же самое, что делает TPersistent.Assign() (так как он не использует Generics).

Подтвержденный ответ: автор не нашел полного решения проблемы, но узнал следующее:

  1. Решение Реми подходит, если базовый класс элемента (здесь TBaseCopyable) не имеет состояния и либо является абстрактным, либо методы не нуждаются в ссылке на другие объекты того же типа.
  2. Важным вопросом является specify generic class, чьи descendant classes могут specify method arguments и return values того же типа, что и их окружающий класс. В примере Реми это достигается в declaration descendant class:
TMyCopyable = class(TBaseCopyable<TMyCopyable>)

Это означает, что в generic классе T будет заменен на окончательный класс интереса.

  1. Однако, в generic declaration TBaseCopyable информация о том, что T всегда является TBaseCopyable, недоступна, так что в implementation TBaseCopyable ссылки на объекты типа T не смогут увидеть методы или поля TBaseCopyable.

Это было бы решено, если бы можно было установить constraint на T, чтобы сообщить компилятору, что T является TBaseCopyable.

Автор также отмечает, что эта проблема связана с "Curiously recurring template pattern" и что Delphi не

Создано по материалам из источника по ссылке.

В статье рассматривается проблема создания универсальной коллекции в Delphi XE2 для работы с объектами, имеющими метод Copy(ownType), и способы её решения с помощью generics.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Коллекции ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 11:32:21/0.0060839653015137/1