About the author
In Part 1, I talked about the two new property access specifiers and showed a way of using them. Now, I would like to show another way of using them.
add_Some combines the existing delegates in FOnSome with the new delegate, and assigns it to FOnSome, such that the new delegate is added to the last position.
remove_Some removes the specified delegate from the existing delegates listed in FOnSome, and assigns the result to FOnSome.
Is there a way of clearing the delegate list, or changing the order of insertion of delegates if you're not privy to the declarations?
To be continued...
program MulticastEvents2; {$APPTYPE CONSOLE} uses Classes; type TSomeEvent = procedure; TSomeObject = class private FOnSome: TSomeEvent; procedure add_Some(Value: TSomeEvent); procedure remove_Some(Value: TSomeEvent); public procedure ClearSome; procedure DoSome; property OnSome: TSomeEvent add add_Some remove remove_Some; end; procedure TSomeObject.add_Some(Value: TSomeEvent); begin FOnSome := TSomeEvent(Delegate.Combine(Delegate(@FOnSome), Delegate(@Value))); end; procedure TSomeObject.ClearSome; var List: array of Delegate; I: Integer; begin if Assigned(FOnSome) then begin List := Delegate(@FOnSome).GetInvocationList; for I := 0 to Length(List) - 1 do Exclude(OnSome, TSomeEvent(List)); end; end; procedure TSomeObject.DoSome; begin if Assigned(FOnSome) then FOnSome; end; procedure TSomeObject.remove_Some(Value: TSomeEvent); begin FOnSome := TSomeEvent(System.Delegate.Remove(Delegate(@FOnSome), Delegate(@Value))); end; procedure Some1; begin WriteLn('Hello world, I am Some1'); end; procedure Some2; begin WriteLn('Hello world, I am Some2'); end; procedure Some3; begin WriteLn('Hello world, I am Some3'); end; var SomeObj: TSomeObject; begin SomeObj := TSomeObject.Create; Include(SomeObj.OnSome, Some1); Include(SomeObj.OnSome, Some2); Include(SomeObj.OnSome, Some3); SomeObj.DoSome; WriteLn; WriteLn('All handlers will now be removed...'); WriteLn; SomeObj.ClearSome; SomeObj.DoSome; WriteLn('End of demonstration for add and remove property access specifiers'); ReadLn; end.