Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.11.20;
Скачать: CL | DM;

Вниз

Разные классы, в колекции   Найти похожие ветки 

 
Mim2   (2005-03-17 16:10) [0]

Я как понимаю такое нереально, так как в конструктор колекции мы передаем ссылку на класс итема коллекции. Именно поэтому как я понимаю для полей датасета создали свой редактор (там поля tstringfiled, tintegerfield и т.д.). Или я ошибаюсь?


 
Юрий Зотов ©   (2005-03-17 16:27) [1]

Нереально, конечно. Все элементы коллекции имеют один класс. Иначе как, например, смог бы работать метод Add?

А поля датасета к коллекциям отношения не имеют. Поля - это невидимые компоненты, которые хотя и не видны, но реально присутствует на форме, датасет только содержит их список. Ну а поскольку они не видны, то для работы с ними нужен редактор.


 
jack128 ©   (2005-03-17 17:50) [2]

Юрий Зотов ©   (17.03.05 16:27) [1]
Все элементы коллекции имеют один класс


function TSameCollection.Add: TCollectionItem;
var
 cl: TCollectionItemClass;
begin
 cl := nil;
 if Assigned(FOnGetCollectionItemClass) then
   FOnGetCollectionItemClass(Self, cl);
 if not Assigned(cl) then
   raise Exception.Create("Задайте класс элемента коллекции");
 Result := cl.Create(Self);
end;


 
Юрий Зотов ©   (2005-03-17 18:02) [3]

> jack128 ©   (17.03.05 17:50) [2]

Это очевидно. Но не реализовано.


 
vuk ©   (2005-03-17 18:41) [4]

to Юрий Зотов ©   (17.03.05 16:27) [1]:
>Все элементы коллекции имеют один класс.
Судя по исходникам, получается немного не так. Элементы коллекции должны быть унаследованы от одного класса (того, который задан коллекции при конструировании). Если нужно добавить в коллекцию экземпляр класса, который унаследован от класса заданного при конструировании, но не является им, можно пользоваться методом Create класса TCollectionItem.


constructor TCollectionItem.Create(Collection: TCollection);
begin
 SetCollection(Collection);
end;

procedure TCollectionItem.SetCollection(Value: TCollection);
begin
 if FCollection <> Value then
 begin
   if FCollection <> nil then FCollection.RemoveItem(Self);
   if Value <> nil then Value.InsertItem(Self);
 end;
end;

procedure TCollection.InsertItem(Item: TCollectionItem);
begin
 if not (Item is FItemClass) then TList.Error(@SInvalidProperty, 0);
 FItems.Add(Item);
 Item.FCollection := Self;
 Item.FID := FNextID;
 Inc(FNextID);
 SetItemName(Item);
 Notify(Item, cnAdded);
 Changed;
 NotifyDesigner(Self, Item, opInsert);
end;


Как видно, проверка типа вставляемого элемента производится при помощи is, а не простым сравнением, что позволяет добавлять в коллекцию элементы разных классов.


 
vuk ©   (2005-03-17 18:41) [5]

>методом Create
Конструктором, конечно же.


 
Юрий Зотов ©   (2005-03-17 18:52) [6]

> vuk ©   (17.03.05 18:41) [4]

Да, так, конечно, точнее.


 
Набережных С. ©   (2005-03-17 20:03) [7]


> vuk ©   (17.03.05 18:41) [4]

Что-то я не понял:( Как можно воспользоваться конструктором класса элемента коллекции (того класса, который передан в конструктор коллекции) для добавления в коллекцию элементов разных классов? Без кардинальной переработки всей инфраструктуры поддержки коллекций? Не, не въезжаю:( Пример можно?


 
vuk ©   (2005-03-17 20:34) [8]

to Набережных С. ©   (17.03.05 20:03) [7]:
>Пример можно?
TMyCollectionItem.Create(SomeCollection);


 
vuk ©   (2005-03-17 20:43) [9]

Или, если угодно, развернутый пример для компиляции.

program Project1;

{$APPTYPE CONSOLE}

uses
 SysUtils, Classes;

type
 TMyItem = class(TCollectionItem)
   procedure DoSomething; virtual;
 end;

 TMyExtItem = class(TMyItem)
   procedure DoSomething; override;
 end;

 TOtherItem = class(TCollectionItem)
   procedure DoAnotherThing;
 end;

procedure TMyItem.DoSomething;
begin
 writeln("TMyItem.DoSomething");
end;
procedure TMyExtItem.DoSomething;
begin
 writeln("TMyExtItem.DoSomething");
end;

procedure TOtherItem.DoAnotherThing;
begin
 writeln("TOtherItem.DoAnotherThing");
end;

var
 C: TCollection;
 i: integer;
 Current: TCollectionItem;
begin
 C := TCollection.Create(TCollectionItem);
 try
   TMyItem.Create(c);
   TMyExtItem.Create(c);
   TOtherItem.Create(c);

   for i := 0 to c.count - 1 do
   begin
     Current := c.Items[i];
     if Current is TMyItem then
       TMyItem(Current).DoSomething
     else
     if Current is TOtherItem then
       TOtherItem(Current).DoAnotherThing;
   end;
 finally
   C.Free;
 end;
 readln;
end.


 
Набережных С. ©   (2005-03-17 20:51) [10]


> vuk ©   (17.03.05 20:34) [8]

Ну то есть чисто в ран-тайм, в обход Add. И вся инфраструктура режима дизайна побоку. Вообще-то конференция называется "Компоненты", если кто не заметил:))


 
Набережных С. ©   (2005-03-17 20:55) [11]

Все-таки надо ветку обновлять, перед отправкой:)

> vuk ©   (17.03.05 20:43) [9]

Да не обязательно было, и так все ясно. См.[10]:)))


 
vuk ©   (2005-03-17 21:06) [12]

to Набережных С.:
>Ну то есть чисто в ран-тайм, в обход Add.
Вообще говоря да. Все это барахло не сможет быть прочитано из потока, хотя и запишется без проблем. Это проблема стандартных коллекций. Они являются полиморфными, но файлеры не имеют поддержки этого полиморфизма.

В принципе, если сильно захотеть, можно написать свои collection-подобные классы, которые будут обеспечивать полиморфизм при загрузке, но для этого придется регистрировать загружаемые классы и поковыряться с сохранением свойств.


 
Набережных С. ©   (2005-03-17 21:15) [13]


> vuk ©   (17.03.05 21:06) [12]

Это конечно. Плюс к тому и собственный редактор коллекции. И даже возможно, что в каком-то особом случае может появиться смысл все это сделать, но возни будет довольно много, по-моему.


 
vuk ©   (2005-03-17 21:25) [14]

to Набережных С. ©   (17.03.05 21:15) [13]:
Я такие вещи делал, правда, без designtime поддержки, но в потоках это все жило на ура. У меня мообще в полузаброшенном состоянии имеется свой набор контейнерных классов. Иногда использую, когда возможностей стандартных не хватает.


 
Набережных С. ©   (2005-03-17 21:32) [15]


> vuk ©   (17.03.05 21:25) [14]

Да, для "внутреннего употребления" - вопроса нет, и сам делал. Я-то имел в виду возню с поддержкой режима дизайна.


 
Cobalt ©   (2005-03-18 09:39) [16]

А можно примерчик, когда может потребоваться в Дизайне задать разные элементы коллекции?


 
Mim2   (2005-03-18 09:54) [17]

Я в вопросе забыл оговориться что разые классы это всеже наследники некого предка задаваемого при создании колекции, рад что вы меня поняли :)...
Спасибо за развернутое обьяснение, буду писать колекции подобный класс и дизайнер для него...

> Cobalt ©   (18.03.05 09:39) [16]
> А можно примерчик, когда может потребоваться в Дизайне задать
> разные элементы коллекции?

Чисто теоритически можно было тотже TField пронаследовать от TCollectionItem, а уже наследники tfield типо tstringfield размещать в коллекции, это избавило бы разрабочиков (VCL) от необходимости писать свой дизайнер ...


 
Юрий Зотов ©   (2005-03-18 10:48) [18]

> Mim2   (18.03.05 09:54) [17]

Просто поля в VCL были сразу, а коллекции появились позже.


 
vuk ©   (2005-03-18 13:51) [19]

to Mim2   (18.03.05 09:54) [17]:
>Чисто теоритически можно было тотже TField пронаследовать от
>TCollectionItem
Чисто теоретически можно, но практически, как уже сказано, из потока грузиться не будет из-за механизма загрузки коллекций.



Страницы: 1 вся ветка

Текущий архив: 2005.11.20;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.049 c
8-1120128938
КиТаЯц
2005-06-30 14:55
2005.11.20
Как обрезать картинку?


2-1131229226
zaN0za
2005-11-06 01:20
2005.11.20
Подскажите пожалуйста, что я делаю не правильно.


2-1130511655
Yura32
2005-10-28 19:00
2005.11.20
IP


14-1128758475
Kerk
2005-10-08 12:01
2005.11.20
[Порка] WordLines 2 Final


2-1130435828
Yus
2005-10-27 21:57
2005.11.20
Классы