将对象转换为没有TInterfacedObject的接口类型作为基类 [英] Casting object to interface type with no TInterfacedObject as base class
问题描述
我需要一个没有引用计数的类实现接口。我做了以下:
I need a class implementing interface with no reference counting. I did the following:
IMyInterface = interface(IInterface)
['{B84904DF-9E8A-46E0-98E4-498BF03C2819}']
procedure InterfaceMethod;
end;
TMyClass = class(TObject, IMyInterface)
protected
function _AddRef: Integer;stdcall;
function _Release: Integer;stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult;stdcall;
public
procedure InterfaceMethod;
end;
procedure TMyClass.InterfaceMethod;
begin
ShowMessage('The Method');
end;
function TMyClass.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
function TMyClass._AddRef: Integer;
begin
Result := -1;
end;
function TMyClass._Release: Integer;
begin
Result := -1;
end;
缺少引用计数工作正常。但是我担心的是,我不能将 TMyClass
转换为 IMyInterface
使用作为
operator:
Lack of reference counting works fine. But my concern is that I cannot cast TMyClass
to IMyInterface
using as
operator:
var
MyI: IMyInterface;
begin
MyI := TMyClass.Create as IMyInterface;
我给了
[DCC错误] E2015操作符不适用于此操作数类型
[DCC Error] E2015 Operator not applicable to this operand type
当 TMyClass时,问题消失
派生自 TInterfacedObject
- 即我可以做这样的投射,没有编译器错误。显然,我不想使用TInterfacedObject作为基类,因为它会使我的类引用计数。为什么这样的投票不允许,如何解决它?
The problem disappears when TMyClass
derives from TInterfacedObject
- i.e. I can do such casting without compiler error. Obviously I do not want to use TInterfacedObject as a base class as it would make my class reference counted. Why is such casting disallowed and how one would workaround it?
推荐答案
你不能使用 / code>在你的代码是你的类没有明确地列出支持的接口列表中的
IInterface
。即使您的界面来自 IInterface
,除非您实际列出了该界面,否则您的课程不支持。
The reason you cannot use as
in your code is that your class does not explicitly list IInterface
in its list of supported interfaces. Even though your interface derives from IInterface
, unless you actually list that interface, your class does not support it.
所以,这个简单的修复就是这样声明你的类:
So, the trivial fix is to declare your class like this:
TMyClass = class(TObject, IInterface, IMyInterface)
你的类需要实现 IInterface
的原因是是为了实现作为
演员而编译器所依赖的。
The reason that your class needs to implement IInterface
is that is what the compiler is relying on in order to implement the as
cast.
另一点我想make是一般你应该避免使用接口继承。总的来说,它的目的很少。使用接口的好处之一是您不需要实现继承附带的单一继承约束。
The other point I would like to make is that you should, in general, avoid using interface inheritance. By and large it serves little purpose. One of the benefits of using interfaces is that you are free from the single inheritance constraint that comes with implementation inheritance.
但是无论如何,所有Delphi接口自动继承 IInterface
,所以在你的情况下没有指出这一点。我会声明你的界面如下:
But in any case, all Delphi interfaces automatically inherit from IInterface
so in your case there's no point specifying that. I would declare your interface like this:
IMyInterface = interface
['{B84904DF-9E8A-46E0-98E4-498BF03C2819}']
procedure InterfaceMethod;
end;
更广泛的是,您应该尽量不要在接口上使用继承。通过采取这种方法,您将鼓励更少的耦合,并导致更大的灵活性。
More broadly you should endeavour not to use inheritance with your interfaces. By taking that approach you will encourage less coupling and that leads to greater flexibility.
这篇关于将对象转换为没有TInterfacedObject的接口类型作为基类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!