将对象转换为没有TInterfacedObject的接口类型作为基类 [英] Casting object to interface type with no TInterfacedObject as base class

查看:181
本文介绍了将对象转换为没有TInterfacedObject的接口类型作为基类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个没有引用计数的类实现接口。我做了以下:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆