Einzelnen Beitrag anzeigen

einbeliebigername

Registriert seit: 24. Aug 2004
140 Beiträge
 
Delphi XE8 Professional
 
#2

AW: TNotifyEvent Objektbezogen in Variable speichern #2

  Alt 16. Jan 2012, 18:38
Hallo,

ich habe bis heute Ereignisse auch mit @Ereigniss1= @Ereigniss2 verglichen. Ich glaube das stand sogar mal in der Hilfe zu Delphi so drin. Jedenfalls wird/wurde es so auch in der VCL gemacht, wie man an einem Auszug von Controls.pas aus Delphi 2007 sehen kann:
Delphi-Quellcode:
function TControlActionLink.IsOnExecuteLinked: Boolean;
begin
  Result := inherited IsOnExecuteLinked and
    (@FClient.OnClick = @Action.OnExecute);
end;
Aber irgendwie will das nicht mehr.

In Delphi XE sieht die obige Funktion so aus.
Delphi-Quellcode:
function TControlActionLink.IsOnExecuteLinked: Boolean;
begin
  Result := inherited IsOnExecuteLinked and ((
{$IF DEFINED(CLR)}

    (not Assigned(FClient.OnClick)) and (not Assigned(Action.OnExecute))) or
     (Assigned(FClient.OnClick) and
{$IFEND}
      DelegatesEqual(@FClient.OnClick, @Action.OnExecute)));
end;
Wobei DelegatesEqual so aus sieht:
Delphi-Quellcode:
function DelegatesEqual(A, B: Pointer): Boolean;
begin
  Result := A = B;
end;
Das funktioniert in deinem Fall aber auch nicht. Die Hilfe zu DelegatesEqual ist ja auch interessant:
Zitat:
DelegatesEqual überprüft, ob zwei Delegaten gleich sind.

DelegatesEqual wird aus Gründen der Kompatibilität mit .NET bereitgestellt. DelegatesEqual hat in Win32-Anwendungen keinen echten Nutzen.
Wird aber bei Win32 kräftig benutzt.

So ein Ereignis ist ja ein Methodenzeiger, der aus zwei Zeigern besteht. Einer zeigt auf die Methode in der Klasse und der andere auf das Objekt, unter dessen Kontext die Methode aufgerufen werden soll. Im Hintergrund wird das über den Type TMethod behandelt, der so aussieht:
Delphi-Quellcode:
  TMethod = record
    Code, Data: Pointer;
  end;
Der Vergleich @Ereigniss1= @Ereigniss2 scheint nur den ersten Zeiger zu vergleichen, der bei dir ja gleich ist, und den Zweiten zu ignorieren.

Wenn man in deinem Fall den Vergleich so macht:
(TMethod(THAL_ObserverItem(FListSubscriber[i]).Event).Data = TMethod(_Event).Data) and (TMethod(THAL_ObserverItem(FListSubscriber[i]).Event).Code = TMethod(_Event).Code) funktioniert das unter Delphi 2007 und XE. Die Frage ist bloß, funktioniert das auch ab XE2 unter jeder Plattform so und wie muss man das unter .NET machen? Die nächste Frage wäre, wieso bei TMethod die Vergleichsoperatoren Equal und NotEqual nicht überschrieben wurden, damit folgendes reichen würde?
TMethod(THAL_ObserverItem(FListSubscriber[i]).Event) = TMethod(_Event) Ich habe auch bei XE getestet ob der Compiler-Schalter {$T} Auswirkungen hat, was nicht der Fall ist.

@All: Nun die Preisfrage, wieso wird in der VCL an entscheidenden Stellen Ereignisse mittels @ verglichen?

Einbeliebigername.
  Mit Zitat antworten Zitat