![]() |
Klasse eines Objekts zur Laufzeit ändern
Mit folgender Prozedure ist es möglich, die Klasse eines Objekts zur Laufzeit zu ändern.
Wichtig dabei ist, dass die neue Klasse immer ein direkter Nachkomme der Klasse des Objekts ist. Ausserdem kann man in der neuen Klasse nur virtuelle Methoden überschreiben und keine neuen Felder hinzufügen. Sollte die neue Klasse grösser sein als die alte, wird eine Exception erzeugt. Mit Felder sind hier die lokalen Variablen der Klasse (meist unter Abschnitt private) gemeint. Da das Objekt schon existieren muss, sind Eingriffe in den Konstruktor nicht möglich.
Delphi-Quellcode:
Hier noch ein kleines Anwendungsbeispiel.
procedure ChangeClass(obj : TObject; NewClass:TClass);
type PClass = ^TClass; begin if Assigned(obj) and (obj.ClassType <> NewClass) then begin if obj.ClassType <> NewClass.ClassParent then raise Exception.CreateFmt('can''t change Object of class %s to class %s', [obj.ClassName, NewClass.ClassName]); if obj.InstanceSize <> NewClass.InstanceSize then raise Exception.CreateFmt('Class %s - invalid instance size', [NewClass.ClassName]); PClass(obj)^ := NewClass; end; end;
Delphi-Quellcode:
Siehe auch Tutorial:
// Es wird die Klasse eines Objekts von TButton nach TBeepButton geändert.
type TBeepButton = class(TButton) protected procedure Click;override; end; procedure TBeepButton.Click; begin Beep; inherited; end; procedure TForm1.FormCreate(Sender: TObject); begin ChangeClass(Button1, TBeepButton); end; ![]() |
Re: Klasse eines Objekts zur Laufzeit ändern
Gibt es dafür auch einen praktischen Anwendungsfall? Oder anders gesagt, wann braucht man so was? So unbedarft auf den ersten Blick kommt mir das ziemlich unsauber vor, wenn man so etwas brauchen würde.
|
Re: Klasse eines Objekts zur Laufzeit ändern
Könnte man dann brauchen, wenn man nur Zugriff auf eine Instanz eines Formulares hat und dort vielleicht einen Button austauschen möchte man dies aber leider nicht per Quellcode machen kann, da man nur die dcu Datei hat.
|
Re: Klasse eines Objekts zur Laufzeit ändern
Hallvard Vassbotn hat diesen Hack einmal vorgestellt, als es darum ging, das Flackern von TProgressBars unter Vista abzustellen.
|
Re: Klasse eines Objekts zur Laufzeit ändern
Zitat:
Man könnte bei jedem Zugriff auf ein String-Feld ein TrimRight hinzufügen. Das ist natürlich sehr aufwendig und manchmal gar nicht möglich. Man könnte eine Klasse TTrimedStringField von der Klasse TStringField ableiten. Wenn man dann im Event [TDataSet.]AfterOpen alle TStringField Klassen in TTrimedStringField ändert, kann man das Problem mit wenig Aufwand in der Griff bekommen. Auch bei Anwendung des State Design-Patterns ist das Ändern der Klasse hilfreich. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz