Hallo,
ich habe eine meine eigene Unterklasse TMyObjectList von TObjectList erstellt. Von TMyObjectList gbit es wiederrum eine Unterklasse TTestList, die TTestItems enthalten kann. Ein TTestItem kann ein TTestItemSub
A oder TTestItemSub
B sein. (Ich hab hier nur alle relevanten Teile gepostet, die echte Struktur ist komplexrer, daher muss die Aufteilung der Klassen so sein, wie sie ist.)
Wenn ich nun z.B. wie in Button2Click ein mit TTestItemSubB.Create ein TTestItemSubB erstelle, werden alle Konstruktoren in der Vererbungsreihenfolge aufgerufen:
TMyPersistent.Create
TTestItem.Create
TTestItemSubB.Create
Wenn ich nun allerdings wie z.B. in Button2Click / TMyObjectList<T>.LoadFromFile die Klasse mit T(MyClass.Create) erzeuge, wird KEINER der Konstruktoren aufgerufen. Warum? In TMyObjectList<T>.LoadFromFile möchte ich die Item-Klassen anhand ihres Namens erstellen, der als String aus einer Datei ausgelesen wird. Vermutlich liegt an der Stelle der Fehler?!
Vielen Danke für eure Hilfe!
Delphi-Quellcode:
unit Unit1;
interface
uses
Winapi.Windows,
Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,
Vcl.Controls,
Vcl.Forms,
Vcl.Dialogs, System.Contnrs, System.Generics.Collections,
Vcl.StdCtrls;
type
TMyPersistent =
class(TPersistent)
public
constructor Create;
virtual;
end;
TMyObjectList<T: TMyPersistent,
constructor> =
class(TObjectList<T>)
public
procedure LoadFromFile;
end;
TTestItem =
class(TMyPersistent)
public
constructor Create;
override;
end;
TTestItemSubA =
class(TTestItem)
public
constructor Create;
override;
end;
TTestItemSubB =
class(TTestItem)
public
constructor Create;
override;
end;
TTestList =
class(TMyObjectList<TTestItem>)
end;
TForm1 =
class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
TestList: TTestList;
begin
TestList := TTestList.Create;
try
TestList.LoadFromFile;
finally
TestList.Free;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
TestList: TTestList;
Item: TTestItemSubB;
begin
TestList := TTestList.Create;
try
Item := TTestItemSubB.Create;
TestList.Add(Item);
finally
TestList.Free;
end;
end;
procedure TMyObjectList<T>.LoadFromFile;
var
Item: T;
NewClass:
string;
MyClass: TPersistentClass;
begin
Clear;
NewClass := '
TTestItemSubB';
//das wird für jedes Item aus einer Datei gelesen. Damit es einfacher ist, hier als fester String...
MyClass := GetClass(NewClass);
if Assigned(MyClass)
then
begin
Item := T(MyClass.Create); <-- !!!! hier wird KEIN Konstruktor aufgerufen !!!
Add(Item);
end;
end;
constructor TTestItemSubA.Create;
begin
inherited;
ShowMessage('
TTestItemSubA.Create');
end;
constructor TTestItemSubB.Create;
begin
inherited;
ShowMessage('
TTestItemSubB.Create');
end;
constructor TMyPersistent.Create;
begin
inherited;
ShowMessage('
TMyPersistent.Create');
end;
constructor TTestItem.Create;
begin
inherited;
ShowMessage('
TTestItem.Create');
end;
initialization
RegisterClasses([TTestItemSubA, TTestItemSubB]);
end.