Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check whether an interfaced object implements another interface?

I have these interface declarations:

IListener = interface
  procedure HandleEvent(AEvent: TMyEvent);
end;

IExtendedListener = interface(IListener)
  ['{85A3456A-D5E5-4F37-ABDD-A75A7B3B494C}']  // required by GetInterface
  procedure HandleExtendedEvent(AExtendedEvent: TMyExtendedEvent);
end;

Given an interface reference for something that implements IListener, how can I check whether it also implements IExtendedListener? I'm using the code below code because it is a compile time error to do something like if Listener is IExtendedListener then ....

TSomeClass.Notify(AEvent: TMyExtendedEvent);
var
  Listener: IListener;
  ExtListener: IExtendedListener;
  Obj: TObject;
begin
  for Listener in FListeners do
  begin
    // works but smells funny
    Obj := Listener as TObject;
    Obj.GetInterface(IExtendedListener, ExtListener);
    if Assigned(ExtListener) then
      ExtNotifyee.HandleExtendedEvent(AEvent);
  end;
end;
like image 742
Lawrence Barsanti Avatar asked Jan 15 '13 16:01

Lawrence Barsanti


1 Answers

You should use Sysutils.Supports to check for a special Interface

uses
  SysUtils;

TSomeClass.Notify(AEvent: TMyExtendedEvent);
var
  Listener    : IListener;
  ExtListener : IExtendedListener;
begin
  for Listener in FListeners do
    if Supports( Listener, IExtendedListener, ExtListener ) then
      ExtListener.HandleExtendedEvent( AEvent );
end;
like image 117
Sir Rufo Avatar answered Oct 13 '22 09:10

Sir Rufo