Irgendwas geht hier nicht mit rechten Dingen zu...
Um "for in" anwenden zu können, brauche ich eine Instanz einer Klasse, die eine funktion GetEnumerator besitzt, welche eine Instanz einer Klasse liefert, die MoveNext, Current und GetCurrent besitzt.
Richtig bisher, oder?
Die Wurzel allen Übels wäre wohl diese Klassen:
Delphi-Quellcode:
type
TControlEnumerator = class
protected
function getOwner: TWinControl;virtual;abstract;
function getPosition: Integer;virtual;abstract;
property Owner :TWinControl read getOwner;
property Position :Integer read getPosition;
public
function getCurrent :TControl; virtual;abstract;
function MoveNext :Boolean; virtual;abstract;
property Current :TControl read getCurrent;
end;
IControlIterator = interface
function getOwner :TWinControl;
function GetEnumerator :TControlEnumerator;
property Owner :TWinControl read getOwner;
end;
TControlIterator = class(TInterfacedObject)
public
class function GetInstance(aOwner :TWinControl) :IControlIterator;overload;
class function GetInstance(aOwner :TWinControl;
aControlClass :TControlClass) :IControlIterator; overload;
end;
Der Enum ist abstrakt, da ich in der
Unit alle Klassen habe, die nach außen hin benötigt werden.
Deshalb sollte hier
IMHO keinerlei Funktionalität reinquetscht werden. (bis auf die Factories...)
Das hier funktioniert sowohl in D7 als auch in D2005:
Delphi-Quellcode:
with TControlIterator.GetInstance(self, TButton).GetEnumerator do
while MoveNext do
ListBox1.Items.Add(Current.Name);
Das hier kompiliert zwar in D2005...
Delphi-Quellcode:
for Control in TControlIterator.GetInstance(self, TButton) do
ListBox1.Items.Add(Control.Name);
...aber er springt zur deklaration von MoveNext in TControlEnumerator und sagt mir "abstract error..."
Haben wir heute den ersten April und ich hab's verpasst?
Wer mal in den angehängten Code schaut dürfte sofort sehen, dass ich eine Instanz des Enums zurückgebe, deren Klasse MoveNext überschreibt...
Ich habe jetzt eine Weile rumgedoktort, aber egal was man versucht: D2005 scheint sich stupide und fix auf die Methoden der Klasse zu stürzen, die GetEnumerator liefert. Ohne auch nur daran zu denken, dass sie überschrieben sein könnten.
Sorry Sharky, ich hab's versucht, aber das ist mir auf Dauer einfach zu doof...
Wie gesagt, ich habe den Code angehängt. Wer was draus machen will: be my guest...