Passing a TInterfacedObject to an Interface

According to the Delphi docs , I can use TInterfacedObjectfor an interface using an operator as.

But this does not work for me. The cast leads to a compilation error: "The operator is not applicable to this type of operand."

I am using Delphi 2007.

Here is the code (console application). The line containing the error is marked.

program Project6;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  IMyInterface = interface
    procedure Foo;
  end;

  TMyInterfacedObject = class(TInterfacedObject, IMyInterface)
  public
    procedure Foo;
  end;

procedure TMyInterfacedObject.Foo;
begin
  ;
end;

var
  o: TInterfacedObject;
  i: IMyInterface;
begin
  try
    o := TMyInterfacedObject.Create;
    i := o as IMyInterface;  // <--- [DCC Error] Project6.dpr(30): E2015 Operator not applicable to this operand type
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
+5
source share
3 answers

Quick response

Your interface must have a GUID for the operator as. Go to the first line after IMyInterface = interface, before any method definitions, and press Ctrl+ Gto generate a new GUID.

as GUID, IUnknown.QueryInterface, GUID. , INTERFACE INTERFACE.

TInterfacedObject , , - (TInterfacedObject), (IMyInterface). , : TObject , - .Free; , .Free . : , , ( - ), . ZERO, (.Free)!

- , :

procedure DoSomething(If: IMyInterface);
begin
end;

procedure Test;
var O: TMyObjectImplementingTheInterface;
begin
  O := TMyObjectImplementingTheInterface.Create;
  DoSomething(O); // Works, becuase TMyObject[...] is implementing the given interface
  O.Free; // Will likely AV because O has been disposed of when returning from `DoSomething`!
end;

: O TMyObject[...] IMyInterface, :

procedure DoSomething(If: IMyInterface);
begin
end;

procedure Test;
var O: IMyInterface;
begin
  O := TMyObjectImplementingTheInterface.Create;
  DoSomething(O); // Works, becuase TMyObject[...] is implementing the given interface
end; // `O` gets freed here, no need to do it manually, because `O` runs out of scope, decreases the ref count and hits zero.
+14

As Supports, Guid , :

type   
  IMyInterface = interface
    ['{00000115-0000-0000-C000-000000000049}']
    procedure Foo;   
  end; 

. docwiki

+2

The cast will be automatic if you define the object o as the correct type. Otherwise, you can always use supports()and / or call QueryInterfaceyourself.

var
  o: TMyInterfacedObject;
  i: IMyInterface;
begin
  try
    o := TMyInterfacedObject.Create;
    i := o;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
0
source

All Articles