Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Дженерик+типизация+наследование+передача через границу bpl / 25 сообщений из 30, страница 1 из 2
17.01.2018, 14:11
    #39585811
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
Доброго дня, коллеги.
Рылся по гуглям, чет скудновато по моей теме.
Код: 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
17.01.2018, 14:50
    #39585855
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
17.01.2018 14:11, Олег Третьяков пишет:
> по задумке дальнейшее наследование Items идет от TCustomItem1 и TCustomItem2 с передачей в TCustomExtention<>

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

Ннадо))

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

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

А если эту структуру нужно будет сортить или искать по ней чего - вот тут generic-ки и в помощь (например, см. TArray в System.Generics.Collections)
...
Рейтинг: 0 / 0
17.01.2018, 17:49
    #39586001
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
Дык объекты использовать стоит только тогда, когда без них не обойтись.
...
Рейтинг: 0 / 0
17.01.2018, 17:56
    #39586005
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
rgreatДык объекты использовать стоит только тогда, когда без них не обойтись.Это как бы всем понятно.
Но массивы записей не всегда удобны. Как раз из-за отсутствия элементарного общего базового функционала в этих самых массивах. Вот тут Generic-и в частности и помогают.
...
Рейтинг: 0 / 0
17.01.2018, 18:18
    #39586013
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
Код: 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
17.01.2018, 18:23
    #39586016
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
Код: 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
17.01.2018, 18:24
    #39586017
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
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
17.01.2018, 18:45
    #39586032
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
rgreatЗацени:
...
Вот тут я совместил плюсы массива, листа и генериков. :)
Ну типа того...
Мне только прямо сейчас восхищаться деталями некогда. Я бегло пробежал.
В целом же похоже на образцовый пример применения дженериков в Дельфях.
...
Рейтинг: 0 / 0
17.01.2018, 18:49
    #39586035
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
Главная фшка в том что это на класс а record на основе массива.
...
Рейтинг: 0 / 0
17.01.2018, 19:23
    #39586057
Leonid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
rgreatГлавная фшка в том что это на класс а record на основе массива.Да это-то как раз понятно из первых 4-х строчек.
Я имею в виду, что не хочу сейчас в даваться в детали конкретной реализации и рассуждать на тему оправданности и оптимальности того или иного. В целом итак видно, что работа по обобщению и замещению продела не малая.
...
Рейтинг: 0 / 0
17.01.2018, 19:27
    #39586059
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
Мимопроходящий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
17.01.2018, 20:58
    #39586078
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
rgreat,

Спасибо, очень интересно.
...
Рейтинг: 0 / 0
17.01.2018, 21:42
    #39586086
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
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
17.01.2018, 21:46
    #39586088
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
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
17.01.2018, 21:55
    #39586090
X-Cite
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
Всмысле не видны...
...
Рейтинг: 0 / 0
17.01.2018, 22:49
    #39586103
Олег Третьяков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
X-Cite,
А внутри TCustomExtention?

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


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

Подобный подход к наименованию ранит мою трепетную душу :)
...
Рейтинг: 0 / 0
18.01.2018, 10:54
    #39586292
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
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
18.01.2018, 13:31
    #39586401
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Дженерик+типизация+наследование+передача через границу bpl
Ок. Надо будет поправить.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Дженерик+типизация+наследование+передача через границу bpl / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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