powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Дженерик+типизация+наследование+передача через границу bpl
25 сообщений из 30, страница 1 из 2
Дженерик+типизация+наследование+передача через границу bpl
    #39585811
Олег Третьяков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго дня, коллеги.
Рылся по гуглям, чет скудновато по моей теме.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
package 
Extentions.Base;
...
TBaseExtention =class;
TBaseItem = class
  private
   fExtention: TBaseExtention;
 public
   a,b,c,d : smallint; 
  constructor Create(const ABaseExtention : TBaseExtention); virtual; 
  procedure Read(const ASource : TMemIniFile; const ASection : string; const AFormatSettings: TFormatSettings); virtual;
  procedure Write(const ADest : TMemIniFile; const ASection : string; const AFormatSettings: TFormatSettings); virtual;
end;

TBaseItemsList<T: TBaseItem> = class(TObjectList<T>)
   private
    fExtention: TBaseExtention;
    function GetItem(AIndex : Word):T;
   public
    constructor Create(const ABaseExtention : TBaseExtention); reintroduce; virtual;
    function NewItem : T; overload;
    function NewItem(AIndex : Word) : T; overload;
    procedure Read(const ASource : TMemIniFile; const ASectionPreff : string; const AFormatSettings: TFormatSettings);
    procedure Write(const ADest : TMemIniFile; const ASectionPreff : string; const AFormatSettings: TFormatSettings);
    property Items[AIndex : Word]:T  read GetItem; default;
  end;
TBaseExtention = class
  procedure Read(const ASource : TMemIniFile; const AFormatSettings: TFormatSettings); virtual; 
  procedure Write(const ADest : TMemIniFile; const AFormatSettings: TFormatSettings); virtual; 
end;
TBaseExtentionClass = class of TBaseExtention;

function ExtentionClass : TBaseExtentionClass;
begin
  result := TBaseExtention;
end; exports ExtentionClass;

....
end.



Extentions.Base компилится и тестируется

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
package 
Extentions.Custom;

...
uses ...Extentions.Base..;

type

TCustomItem1 = class(TBaseItem)
 public
 e, f, g, h : double;
 procedure Read(const ASource : TMemIniFile; const ASection : string; const AFormatSettings: TFormatSettings); override;
 procedure Write(const ADest : TMemIniFile; const ASection : string; const AFormatSettings: TFormatSettings); override;
end;

TCustomItem2<TCI : TCustomItem1> = class(TBaseItem)
 private
  fCI1List : TBaseItemsList<TCI>;
 public
 k,l,m : double;
 constructor Create(const ABaseExtention : TBaseExtention); override;
 //destructor естественно
 procedure Read(const ASource : TMemIniFile; const ASection : string; const AFormatSettings: TFormatSettings); override;
 procedure Write(const ADest : TMemIniFile; const ASection : string; const AFormatSettings: TFormatSettings); override;
 property CI1List : TBaseItemsList<TCI> read fCI1List;
end;

TCustomExtention<T1 : TCustomItem2; T2, T3 : TCustomItem1> = class(TBaseExtention)
//или TCustomExtention<T1 : TCustomItem2<T2>; T3 : TCustomItem1> = class(TBaseExtention)?
private
 fList1 : TBaseItemsList<T1<T2>>;//???
{почти при всех перебранных вариантах декларации и передачи 
не видится property CI1List TCustomItem2 и/или 
 property List1 : TBaseItemsList<T1<T2>> и/или ругается на несовместимость типов
во множестве мест}
 fList2 : TBaseItemsList<T3>;
public
 property List1 : TBaseItemsList<T1<T2>>;//??? read fList1;
 property List2 : TBaseItemsList<T3> read fList2;
 procedure Read(const ASource : TMemIniFile; const AFormatSettings: TFormatSettings); override; 
 procedure Write(const ADest : TMemIniFile; const AFormatSettings: TFormatSettings); override; 
end;

implementation

function ExtentionClass : TBaseExtentionClass;
begin
  result := TCustomExtention<>///как?
end; exports ExtentionClass;

constructor TCustomExtention<T1, T2, T3>.Create(const ABaseExtention : TBaseExtention);
begin
 fList1 : TBaseItemsList<T1<T2>>.Create(Self<{что-то еще?}>);
end;

end.



опробован вариант

Код: pascal
1.
2.
3.
4.
5.
6.
 TCustomItem2List<T1 : TCustomItem1> = class(TBaseItemsList<T1>)
   private
    function GetItem(AIndex : Word):T;
   public
    property Items[AIndex : Word]:T  read GetItem; default;
  end;



Сосбно, как реализуется вложенная параметризация с предопределенным типом, если она возможна вообще?
Гугление не дало однозначного нет.
по задумке дальнейшее наследование Items идет от TCustomItem1 и TCustomItem2 с передачей в TCustomExtention<>
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39585855
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
17.01.2018 14:11, Олег Третьяков пишет:
> по задумке дальнейшее наследование Items идет от TCustomItem1 и TCustomItem2 с передачей в TCustomExtention<>

эта многоступенчатая проктология тебе нужна для зачем?
какова реальная задача?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39585883
Олег Третьяков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий,

Ннадо))

Задача получать экземпляры наследников TCustomItem1 и TCustomItem2, видеть их поля/методы в параметризованном экземпляре TCustomExtention.
Да и вообще разобраться с дженериками, что можно точно, что можно через финт ушами, что скорее всего ректально, а что нельзя в принципе.

Если с первым понятно, со вторым - не все, с третьим и четвертым - надо узнавать
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39585989
Олег Третьяков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Народ, только давайте без религиозного фанатизма разберем инструмент применительно к конкретной задаче.
Адептов устоявшейся парадигмы наверное тоже можно послушать, и только.
Как еще понять полезность и применимость, как не через практику?!
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39585991
Фотография Leonid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatarray [0..0] of TObject
Кстати, динамические массивы в последних Дельфях реально иногда снимают головняк в библиотеках.
Я, например, настоятельно советовал бы отказываться от TStringList-ов в пользу TStringDynArray и подобных же массивов поверх НЕ объектных структур. Т.е. IMHO мелкие объекты, которые нужно списками передавать, но не содержащие внутри других объектов, лучше на record-ы переводить с динамическими массивами.
Просто реально проще жить становится. Особенно когда такие списки из процедур и функций возвращаться должны.

А если эту структуру нужно будет сортить или искать по ней чего - вот тут generic-ки и в помощь (например, см. TArray в System.Generics.Collections)
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586001
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дык объекты использовать стоит только тогда, когда без них не обойтись.
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586005
Фотография Leonid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatДык объекты использовать стоит только тогда, когда без них не обойтись.Это как бы всем понятно.
Но массивы записей не всегда удобны. Как раз из-за отсутствия элементарного общего базового функционала в этих самых массивах. Вот тут Generic-и в частности и помогают.
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586013
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
TCustomExtention<T1 : TCustomItem2; T2, T3 : TCustomItem1> = class(TBaseExtention)
TCustomExtention<T1 : TCustomItem2<T2>; T3 : TCustomItem1> = class(TBaseExtention)


Это же не компилится...
Типа TCustomItem2 нет, есть TCustomItem2<реальный тип> как и TCustomItem2<T2> и т.д.
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586016
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
TCustomExtention<T1: TCustomItem1; T2: TCustomItem2<T1>> = class(TBaseExtention)
  private
    fList1 : TBaseItemsList<T1>;
    fList2 : TBaseItemsList<T2>;
  public
   property List1 : TBaseItemsList<T1> read fList1;
   property List2 : TBaseItemsList<T2> read fList2;
   procedure Read(const ASource : TMemIniFile; const AFormatSettings: TFormatSettings); override;
   procedure Write(const ADest : TMemIniFile; const AFormatSettings: TFormatSettings); override;
  end;


Оно?
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586017
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeonidЭто как бы всем понятно.
Но массивы записей не всегда удобны. Как раз из-за отсутствия элементарного общего базового функционала в этих самых массивах. Вот тут Generic-и в частности и помогают.Зацени:
TArrayEx<T> = record
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
  TArrayEx<T> = record
  public
    // Доступ к элементам напрямую (unsafe)
    Items      : array of T;
    // Пользовательский Тэг
    Tag        : integer;
    // Признак необходимости освобождать элементы при удалении
    DoFreeData : Boolean;
    FEnumInit  : string;
  private
{$IFDEF ArrayExEnumerator}
    type
      TCollection = class;

      TEnumerator = class(TEnumerator<T>)
      private
        FParent : TCollection;
        FIndex  : Integer;
        function GetCurrent: T;
      protected
        function DoGetCurrent: T; override;
        function DoMoveNext: Boolean; override;
      public
        constructor Create(Parent: TCollection);
        property Current: T read GetCurrent;
        function MoveNext: Boolean;
      end;

      TCollection = class(TEnumerable<T>)
      private
        FParent : pointer;
        function GetCount: Integer;
      protected
        function DoGetEnumerator: TEnumerator<T>; override;
      public
        constructor Create(const ArrayEx: TArrayEx<T>);
        function GetEnumerator: TEnumerator<T>; reintroduce;
        property Count: Integer read GetCount;
      end;
{$ENDIF}

    var
      FIndexMod     : integer;                      // Размер индекса
      FIndexArray   : array of array of integer;    // Элементы индекса
      FComparer     : IEqualityComparer<T>;         // Компаратор
{$IFDEF ArrayExEnumerator}
      FCollection   : TCollection;                  // Коллекция для энуметратора
{$ENDIF}

    function GetItems(Index: integer): T; inline;
    procedure SetItems(Index: integer; const Value: T); inline;
    procedure QuickSortA(const Comparer: IComparer<T>; L, R: Integer);
    procedure QuickSortB(L, R: Integer; CompareEvt: TCompareValue<T>; Less, More: TCompareResult);
    function GetIndexMod: integer; inline;
    procedure SetIndexMod(Value: integer); inline;
    procedure HashClear(NewIndexMod: integer); inline;
    procedure HashAdd(const Value: T; Index: integer); inline;
    function GetHash(const Value: T): integer; inline;
    procedure SetIndex(Index: Integer; const Value: T); inline;
    procedure SetCount(const Value: integer); inline;
    function GetCount: integer; inline;
    function GetHigh: integer; inline;
    procedure SetHigh(const Value: integer); inline;
    function GetLow: integer; inline;
    procedure FreeElement(Num: integer); inline;
  public
    // Конструкторы
    constructor Create(DoFreeData: boolean);

    // Доступ к элементам по умолчанию
    property Elements[Index: integer]: T read GetItems write SetItems; default;

    // Очистка массива
    procedure Clear; overload;

    // Добавление элемента(ов) в конец
    function Add(Value: T): integer; overload; inline;
    function Add(Values: array of T): integer; overload;
    function AddUnique(Value: T): integer;

    // Вставка элемента по индексу
    procedure Insert(Index: integer; Value: T); overload; inline;
    procedure Insert(Index: integer; Values: array of T); overload;

    // Удаление элемента по индексу
    procedure Delete(Index: integer); inline;
    procedure DeleteRange(Index, Count: integer); inline;

    // Создание индекса по массиву
    procedure CreateIndex(IndexMod: integer = -1);
    // Уничтожение индекса по массиву
    procedure DropIndex;

    // Кол-во элементов массива
    property Count: integer read GetCount write SetCount;
    // Индекс нижнего элемента массива
    property Low: integer read GetLow;
    // Индекс верхнего элемента массива
    property High: integer read GetHigh write SetHigh;

    // Поиск значения(ий) в массиве
    function Exists(Value: T): boolean; overload;
    function Exists(Values: array of T; NeedAllValues: boolean = False): boolean; overload;
    // Индекс(ы) значения в массиве
    function IndexOf(Value: T): integer;
    function IndexesOf(Value: T): TArrayEx<integer>;

    // Сортировка
    procedure Sort(Comparer: IComparer<T> = nil); overload;
    procedure Sort(CompareEvt: TCompareValue<T>; Mode: TCompareMode = cmAscending); overload;

    // Сериализатор в строку
    function ToString: string; overload;
    function ToString(Delimeter : string): string; overload;

{$IFDEF ArrayExEnumerator}
    function Collection: TCollection;
{$ENDIF}

    class operator Add(const A,B: TArrayEx<T>): TArrayEx<T>; overload;
    class operator Add(const A: TArrayEx<T>; const B: array of T): TArrayEx<T>; overload;
    class operator Add(const A: array of T; const B: TArrayEx<T>): TArrayEx<T>; overload;
    class operator Implicit(const A: TArrayEx<T>): TArray<T>;
{$IF CompilerVersion>27}
    class operator In(const A,B: TArrayEx<T>): Boolean; overload;
    class operator In(const A: array of T; B: TArrayEx<T>): Boolean; overload;
{$ENDIF}
    class operator Equal(const A,B: TArrayEx<T>): Boolean;
    class operator NotEqual(const A,B: TArrayEx<T>): Boolean;
  end;
  {$ENDREGION}


Вот тут я совместил плюсы массива, листа и генериков. :)

http://www.rgreat.ru/tmp/Delphi/Indexes.pas
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586032
Фотография Leonid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatЗацени:
...
Вот тут я совместил плюсы массива, листа и генериков. :)
Ну типа того...
Мне только прямо сейчас восхищаться деталями некогда. Я бегло пробежал.
В целом же похоже на образцовый пример применения дженериков в Дельфях.
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586035
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Главная фшка в том что это на класс а record на основе массива.
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586057
Фотография Leonid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatГлавная фшка в том что это на класс а record на основе массива.Да это-то как раз понятно из первых 4-х строчек.
Я имею в виду, что не хочу сейчас в даваться в детали конкретной реализации и рассуждать на тему оправданности и оптимальности того или иного. В целом итак видно, что работа по обобщению и замещению продела не малая.
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586059
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий17.01.2018 15:18, Олег Третьяков пишет:
> Да и вообще разобраться с дженериками, что можно точно, что можно через финт ушами, что скорее всего ректально, а что нельзя в принципе.

забей.
это нахер ненужные МОДНЫЕ бантики.

Да хотя бы поэтому:
Код: pascal
1.
2.
3.
4.
TQueue<Integer>;
TQueue<Boolean>;
TQueue<string>;
TQueue<TTradeMark>;


и проверка соответствия типов во время компиляции + IntelliSense с корректной типизацией...
Код: pascal
1.
ConcrateTradeMark := Queue.Enqueue();


Вместо
Код: pascal
1.
ConcrateTradeMark := TTradeMark(Queue.Enqueue());
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586078
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

Спасибо, очень интересно.
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586086
Олег Третьяков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
TCustomExtention<T1: TCustomItem1; T2: TCustomItem2<T1>> = class(TBaseExtention)
  private
    fList1 : TBaseItemsList<T1>;
    fList2 : TBaseItemsList<T2>;
  public
   property List1 : TBaseItemsList<T1> read fList1;
   property List2 : TBaseItemsList<T2> read fList2;
   procedure Read(const ASource : TMemIniFile; const AFormatSettings: TFormatSettings); override;
   procedure Write(const ADest : TMemIniFile; const AFormatSettings: TFormatSettings); override;
  end;


Оно?

Неа, не выходит каменный цветок.
Если коротко, не видны члены List2[i].CI1List.____
Реальный код конечно сложнее.
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586088
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
X-CiteМимопроходящий17.01.2018 15:18, Олег Третьяков пишет:
> Да и вообще разобраться с дженериками, что можно точно, что можно через финт ушами, что скорее всего ректально, а что нельзя в принципе.

забей.
это нахер ненужные МОДНЫЕ бантики.

Да хотя бы поэтому:
Код: pascal
1.
2.
3.
4.
TQueue<Integer>;
TQueue<Boolean>;
TQueue<string>;
TQueue<TTradeMark>;



и проверка соответствия типов во время компиляции + IntelliSense с корректной типизацией...
Код: pascal
1.
ConcrateTradeMark := Queue.Enqueue();



Вместо
Код: pascal
1.
ConcrateTradeMark := TTradeMark(Queue.Enqueue());


жуть какая эти ваши генерики

испоганили язык
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586090
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всмысле не видны...
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586103
Олег Третьяков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,
А внутри TCustomExtention?

Код: pascal
1.
2.
3.
4.
procedure TCustomExtention<T1, T2>.Read(const ASource : TMemIniFile; const AFormatSettings: TFormatSettings);
begin
  ?
end;


Или это у меня грабли? Или длинная цепочка наследования? Или хз?!(
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586106
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ctrl + Space - помогает
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586110
Олег Третьяков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,
X-Cite,
Ну почему((
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586146
Олег Третьяков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,
Разобрался, внутри себя нужно кастить к параметру типа.
Осталось понять, как forward declaration и передать self своим контейнерам хотябы с базовым набором параметров класса.
Пока сделал через класс-заглушку.
Спасибо тебе большое!
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586224
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Код: pascal
1.
2.
    // Доступ к элементам по умолчанию
    property Elements[Index: integer]: T read GetItems write SetItems; default;

Подобный подход к наименованию ранит мою трепетную душу :)
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586292
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
white_niggerrgreat
Код: pascal
1.
2.
    // Доступ к элементам по умолчанию
    property Elements[Index: integer]: T read GetItems write SetItems; default;


Подобный подход к наименованию ранит мою трепетную душу :)
не только твою )))
было бы гораздо правильнее
Код: pascal
1.
2.
    // Доступ к элементам по умолчанию
    property Elements[Index: integer]: T read GetElement write SetElement; default;
...
Рейтинг: 0 / 0
Дженерик+типизация+наследование+передача через границу bpl
    #39586401
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ок. Надо будет поправить.
...
Рейтинг: 0 / 0
25 сообщений из 30, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Дженерик+типизация+наследование+передача через границу bpl
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]