delphi - 将 TInterfacedObject 转换为接口(interface)

标签 delphi interface delphi-2007

According to the Delphi docs ,我可以使用 as 运算符将 TInterfacedObject 转换为接口(interface)。

但这对我不起作用。强制转换会产生编译错误:“运算符不适用于此操作数类型”。

我使用的是 Delphi 2007。

这是一些代码(控制台应用程序)。包含错误的行已被标记。

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.

最佳答案

快速回答

您的界面需要有一个 GUID,as 运算符才能工作。转到 IMyInterface = interface 之后、任何方法定义之前的第一行,然后按 Ctrl+G 生成新的 GUID。

更长的评论

接口(interface)的 as 运算符需要 GUID,因为它调用 IUnknown.QueryInterface,而后者又需要 GUID。如果您在将 INTERFACE 转换为其他类型的 INTERFACE 时遇到此问题,那也没关系。

您不应该首先将 TInterfacedObject 转换为接口(interface),因为这意味着您同时持有对实现对象的引用 (TInterfacedObject )和对已实现接口(interface)(IMyInterface)的引用。这是有问题的,因为您混合了两个生命周期管理概念:TObject 一直存在,直到有东西调用 .Free 为止;您有理由确信没有任何东西会在您不知情的情况下调用您的对象上的 .Free 。但是接口(interface)是引用计数的:当您将接口(interface)分配给变量时,引用计数器会增加,当该实例超出范围(或分配了其他内容)时,引用计数器会减少。当引用计数器为零时,该对象将被释放(.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.

关于delphi - 将 TInterfacedObject 转换为接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5448013/

相关文章:

java - 接口(interface)方法对所有实现类都没有意义

python - C++调用Python如何处理SystemExit异常

Java接口(interface)问题

multithreading - Delphi 2007 AsyncMultiSync 不起作用

ios - Delphi FireMonkey 中的 UIView animateWithDuration

delphi - 如何判断字符串中的所有字符是否相等

delphi - 将 VirtualStringTree 导出到 excel、csv?

Delphi ADOConnection 连接超时属性不起作用

delphi - 有什么方法可以改变Delphi2007 IDE中Code Insight红色 'underline'的颜色吗?

delphi - 使用临时变量改变格式化输出