Noch eine Merkwürdigkeit im Zusammenhang mit anonymen Methoden:
Eine anonyme Methode ist nach außen hin nur ein einfacher Pointer. Ein
SizeOf(TProc) liefert also unter 32 Bit erwartungsgemäß 4 Byte. Im Gegensatz dazu bestehen Objekt-Methoden aus einem Daten- und einem Code-Pointer. Deshalb liefert
SizeOf(TMethod)=8 (unter 32 Bit).
Jetzt sollte man natürlich annehmen, daß der doppelt so große Wert von TMethod nicht zuweisungskompatibel zum "kleineren" TProc ist.
Entgegen jeder Logik funktioniert das aber doch: Der Compiler generiert bei einer derartigen Zuweisung einfach eine anonyme Methode und bindet die Variable
Self, die zu der Objekt-Methode gehört.
Ich finde dieses Verhalten genial, da damit Ereignishandler wahlweise Objekt- oder anonyme Methoden sein können.
Ein kleines Beispiel:
Delphi-Quellcode:
type
TNotifyProc = TProc<TObject>; //anstelle von TNotifyEvent
TMyObject = class
private
FValue: Integer;
FOnChange: TNotifyProc;
procedure SetValue(Value: Integer);
public
property Value: Integer read FValue write SetValue;
property OnChange: TNotifyProc read FOnChange write FOnChange;
end;
TForm1 = class(TForm)
[...]
private
procedure MyObjectChange(Sender: TObject);
end;
procedure TMyObject.SetValue(Value: Integer);
begin
if FValue<>Value then
begin
FValue:=Value;
if assigned(FOnChange)
then FOnChange(Self);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyObject: TMyObject;
begin
MyObject:=TMyObject.Create;
try
MyObject.OnChange:=MyObjectChange;
MyObject.Value:=1;
MyObject.OnChange:=procedure(Sender: TObject)
begin
ShowMessage(IntToStr(TMyObject(Sender).Value));
end;
MyObject.Value:=2;
finally
MyObject.Free;
end;
end;
procedure TForm1.MyObjectChange(Sender: TObject);
begin
ShowMessage(IntToStr(TMyObject(Sender).Value));
end;