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/