| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Generics в Delphi XE2 |
| Автор: omickron 28.12.2012, 16:13 | ||||
| Пытаюсь разобраться с дженериками в Delphi XE2. Не понимаю, чем отличается TMyClass<T> = class(TObject) от TMyClass<T: class> = class(TObject) Хочу сделать следующее:
Порядок использования:
Суть в том, чтобы перед началом работы зарегистрировать в фабрике всех наследников TMyClass, а потом создавать их, зная только имя. Но не пойму, чем отличается TMyClass<T> от TMyClass<T: class> Если использовать второй вариант, то ругается здесь: TMyFactory.RegisterType(TMyClass1); //[DCC Error] Incompatible types: 'TMyClass' and 'class of TMyClass1' Т.е. хочет, чтоб я передал TMyClass1.Create. А я не хочу создавать объект сейчас. Я хочу просто зарегистрировать тип. Как нужно описать тип TFactory? |
| Автор: Illusion Dolphin 28.12.2012, 18:38 | ||||
В первом случае T - любой тип, во втором T должен быть классом. TFactory<TMyClass> - значит что T это объекты типа TMyClass. Чтобы туда добавлять типы объектов, надо сделать:
|
| Автор: bems 28.12.2012, 20:48 |
| не очень понятно зачем тебе тут дженерики. с этой задачей метаклассы отлично справлялись задолго до них. разве что для того чтобы возвращать тип, который уже не нужно приводить |
| Автор: omickron 29.12.2012, 23:44 |
| bems, Вы совершенно правы. У меня уже есть функционал, который работает, но приходится делать приведение типов. Я перешёл на XE2 и хочу переписать это с использованием дженериков. Если это, конечно, возможно Illusion Dolphin, скажите, а что означает такая конструкция: TMyClass<T: constructor> = class(TObject) Если я правильно понимаю, означает ли это, что тип, передаваемый в T, должен иметь конструктор без параметров? И тогда можно будет в коде написать что-то вроде Result := T.Create; ? Как бы указать в параметризации, что я хочу параметризовать класс не объектом, а его типом: не TMyClass, а class of TMyClass. Если я укажу TFactory<T: class>, это будет означать, что я должен параметризовать его типом TMyClass. А мне нужно параметризовать его типом class of TMyClass. |
| Автор: Illusion Dolphin 30.12.2012, 10:16 | ||||||
Точно так:
Вот пример реализации того что в первом посте:
P.S. Практического смысла тут не вижу. |
| Автор: omickron 30.12.2012, 10:49 |
| Illusion Dolphin, смысл в том, чтобы сделать общую фабрику, которая будет оперировать типами классов (class of TMyClass). TFactory<T> = class(TObject). А потом TMyClassType = class of TMyClass и TMyFactory = class(TFactory<TMyClassType>). И TMyFactory будет отдавать зарегистрированные типы по имени. Вот есть общая фабрика TFactory<T> и у неё есть метод GetElement(Name: string): T; и её наследник: TMyClassFactory = class(TFactory<TMyClass>) Что будет возвращать GetElement? TMyClass или TMyClass.Create? Созданный объект или тип объекта? * Если указать TFactory<T>, T - любой тип. * Если указать TFactory<T: class>, в T можно передавать только классы. * Если указать TFactory<T: class, constructor>, в T можно передавать классы, у которых есть конструктор без параметров. Что во всех этих случаях будет возвращать GetElement: T? И что нужно указать вместе с T, чтобы передавать не TMyClass, а TMyClassType? |
| Автор: Illusion Dolphin 30.12.2012, 11:00 | ||||||
при:
GetElement возвращает объекты типа TMyClass (т.е. созданные объекты)
? Я не понимаю, в чём проблема. |
| Автор: omickron 30.12.2012, 11:06 | ||||
А как объявить TFactory<?>, чтоб эта общая фабрика знала, что она будет параметризована типом объекта? Например, чтоб можно было сделать такой метод:
Осталось понять только это |
| Автор: Illusion Dolphin 30.12.2012, 11:42 | ||
Если я правильно понял, то тут RTTI надо:
P.S. Сделал хранилище типом TDictionary<string, TClass> |
| Автор: omickron 30.12.2012, 11:44 |
| Ага. Спасибо. Изучу этот аспект. Возможно, то, что надо |