Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.149.229.253] |
|
Сообщ.
#1
,
|
|
|
Вот такой код:
{$APPTYPE CONSOLE} type TMy = class constructor Create; overload; virtual; abstract; end; TMyClass = class of TMy; TMy<T: class> = class(TMy) constructor Create; overload; override; constructor Create(Obj: T); overload; virtual; procedure Test; end; TMy2<T: class> = class(TMy<T>) constructor Create; overload; override; end; constructor TMy<T>.Create; begin WriteLn('TMy<T>'); end; constructor TMy<T>.Create(Obj: T); begin WriteLn('TMy<T>.', Obj.ClassName); end; procedure TMy<T>.Test; begin WriteLn('Test of ', ClassName); end; constructor TMy2<T>.Create; begin WriteLn('TMy2<T>'); end; function Make(TC: TMyClass): TMy; begin Result := TC.Create; end; var T: TMy<TObject>; begin T := TMy<TObject>(Make(TMy<TObject>)); T.Test; T := TMy<TObject>(Make(TMy2<TObject>)); T.Test; end. Т.е. задумка такая, что Make принимает ссылку на класс (метакласс) и возвращает объект этого класса. Проблема в том, что во-первых, я не могу в Make использовать конструктор Create(Obj: T), а во-вторых конструкция TMy<TObject>(Make(TMy<TObject>)) мне кажется костыльной. Проблему можно было бы решить, если бы вместо TMyClass можно было бы использовать TMyClass<T>, однако Delphi рагуется на: type TMyClass<T> = class of TMy<T>; // Error: E2508 Type parameters not allowed on this type И даже так не работает: {$APPTYPE CONSOLE} type TMy = class constructor Create; overload; virtual; abstract; end; TMy<T: class> = class(TMy) type ObjType = TMy<T>; ClassType = class of ObjType; // Error: E2021 Class type required constructor Create; overload; override; constructor Create(Obj: T); overload; virtual; procedure Test; end; TMy2<T: class> = class(TMy<T>) constructor Create; overload; override; end; constructor TMy<T>.Create; begin WriteLn('TMy<T>'); end; constructor TMy<T>.Create(Obj: T); begin WriteLn('TMy<T>.', Obj.ClassName); end; procedure TMy<T>.Test; begin WriteLn('Test of ', ClassName); end; constructor TMy2<T>.Create; begin WriteLn('TMy2<T>'); end; function Make(TC: TMy<TObject>.ClassType): TMy<TObject>; begin Result := TC.Create; end; var T: TMy<TObject>; begin T := Make(TMy<TObject>); T.Test; T := Make(TMy2<TObject>); T.Test; end. Как можно решить проблему? Единственный рабочий вариант – такой, но это извращение: {$APPTYPE CONSOLE} type TMy<T: class> = class type TMy = class constructor Create; overload; virtual; constructor Create(Obj: T); overload; virtual; procedure Test; end; ClassType = class of TMy; end; TMy1<T: class> = class(TMy<T>.TMy) end; TMy2<T: class> = class(TMy1<T>) constructor Create; overload; override; constructor Create(Obj: T); overload; override; end; constructor TMy<T>.TMy.Create; begin WriteLn('TMy<T>.TMy'); end; constructor TMy<T>.TMy.Create(Obj: T); begin WriteLn('TMy<T>.TMy(TObject)'); end; procedure TMy<T>.TMy.Test; begin WriteLn('Test'); end; constructor TMy2<T>.Create; begin WriteLn('TMy2<T>'); end; constructor TMy2<T>.Create(Obj: T); begin WriteLn('TMy2<T>(TObject)'); end; function Make(TC: TMy<TObject>.ClassType): TMy<TObject>.TMy; begin Result := TC.Create(TObject.Create); end; var T: TMy<TObject>.TMy; begin T := Make(TMy1<TObject>); T.Test; T := Make(TMy2<TObject>); T.Test; end. |
Сообщ.
#2
,
|
|
|
Никак. Твой воркэраунд - единственное сколько нибудь адекватное решение
|
Сообщ.
#3
,
|
|
|
Печально, но ладно...
|