如何检查类是否实现了一个接口,遵守超集? [英] How to check if a class implements an interface, with respecting supersets?

查看:162
本文介绍了如何检查类是否实现了一个接口,遵守超集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习COM和Interfaces,并有以下实验代码:

  type 
IA = interface )
['{C9C5C992-3F67-48C5-B215-7DCE6A61F0E8}']
end;

IB = interface(IA)
['{F1799437-AD12-471B-8716-F1D93D1692FC}']
end;

IC = interface(IB)
['{01780E8C-C47D-468E-8E42-4BFF3F495D51}']
end;

TBO = class(TInterfacedObject,IB)
end;

procedure TForm1.FormCreate(Sender:TObject);
var
x:TBO;
a:IInterface;
begin
x:= TBO.Create;
IInterface(x)._ AddRef;

如果Assigned(TBO.GetInterfaceEntry(IA))then memo1.lines.add('GetInterfaceEntry IA:OK'); // 为什么不?
if Assigned(TBO.GetInterfaceEntry(IB))then memo1.lines.add('GetInterfaceEntry IB:OK');
if Assigned(TBO.GetInterfaceEntry(IC))then memo1.lines.add('GetInterfaceEntry IC:OK');

if x.QueryInterface(IA,a)= S_OK then memo1.lines.add('QueryInterface TA:OK'); // 为什么不?
if x.QueryInterface(IB,a)= S_OK then memo1.lines.add('QueryInterface TB:OK');
if x.QueryInterface(IC,a)= S_OK then memo1.lines.add('QueryInterface TC:OK');

如果支持(TBO,IA),则memo1.lines.add('支持TA:OK'); // 为什么不?
if支持(TBO,IB)then memo1.lines.add('支持TB:OK');
if支持(TBO,IC)then memo1.lines.add('Supports TC:OK');

if支持(x,IA,a)then memo1.lines.add('支持(2)TA:OK'); // 为什么不?
if支持(x,IB,a)then memo1.lines.add('支持(2)TB:OK');
if支持(x,IC,a)then memo1.lines.add('支持(2)TC:OK');
end;

输出:

 code> GetInterfaceEntry IB:OK 
QueryInterface TB:OK
支持TB:OK
支持(2)TB:OK

但我需要:

  GetInterfaceEntry IA:OK 
GetInterfaceEntry IB:OK
QueryInterface TA:OK
QueryInterface TB:OK
支持TA:OK
支持TB:OK
支持(2)TA:OK
支持(2)TB:OK



我理解 IB 是由于接口继承的 IA 的超集。在我的理解中,由于 TBO 实现 IB ,它自动实现 IA 。但为什么 Supports() QueryInterface() GetInterfaceEntry() return false?



如何查询 TBO implements code>直接OR间接,即通过实现 IA 的超集?我需要两个静态类函数,如 GetInterfaceEntry 和一个动态对象引用变量,如 QueryInterface

解决方案

这是Delphi的一个已知怪癖。即使 IB 继承自 IA TBO IA IB 检索两个接口。

  TBO = class(TInterfacedObject,IA,IB)
/ pre>

我忘了技术原因。与编译器为 TBO 生成接口表的限制有关的一些事情。它不会自动包含继承的接口。


I am learning about COM and Interfaces and have following experimental code:

type
  IA = interface(IInterface)
  ['{C9C5C992-3F67-48C5-B215-7DCE6A61F0E8}']
  end;

  IB = interface(IA)
  ['{F1799437-AD12-471B-8716-F1D93D1692FC}']
  end;

  IC = interface(IB)
  ['{01780E8C-C47D-468E-8E42-4BFF3F495D51}']
  end;

  TBO = class(TInterfacedObject, IB)
  end;

procedure TForm1.FormCreate(Sender: TObject);
var
  x: TBO;
  a: IInterface;
begin
  x := TBO.Create;
  IInterface(x)._AddRef;

  if Assigned(TBO.GetInterfaceEntry(IA)) then memo1.lines.add('GetInterfaceEntry IA: OK'); // Why not?
  if Assigned(TBO.GetInterfaceEntry(IB)) then memo1.lines.add('GetInterfaceEntry IB: OK');
  if Assigned(TBO.GetInterfaceEntry(IC)) then memo1.lines.add('GetInterfaceEntry IC: OK');

  if x.QueryInterface(IA, a)=S_OK then memo1.lines.add('QueryInterface TA: OK'); // Why not?
  if x.QueryInterface(IB, a)=S_OK then memo1.lines.add('QueryInterface TB: OK');
  if x.QueryInterface(IC, a)=S_OK then memo1.lines.add('QueryInterface TC: OK');

  if Supports(TBO, IA) then memo1.lines.add('Supports TA: OK'); // Why not?
  if Supports(TBO, IB) then memo1.lines.add('Supports TB: OK');
  if Supports(TBO, IC) then memo1.lines.add('Supports TC: OK');

  if Supports(x, IA, a) then memo1.lines.add('Supports(2) TA: OK'); // Why not?
  if Supports(x, IB, a) then memo1.lines.add('Supports(2) TB: OK');
  if Supports(x, IC, a) then memo1.lines.add('Supports(2) TC: OK');
end;

Output:

GetInterfaceEntry IB: OK
QueryInterface TB: OK
Supports TB: OK
Supports(2) TB: OK

But I need:

GetInterfaceEntry IA: OK
GetInterfaceEntry IB: OK
QueryInterface TA: OK
QueryInterface TB: OK
Supports TA: OK
Supports TB: OK
Supports(2) TA: OK
Supports(2) TB: OK

I understand that IB is a superset of IA due to the Interface inheritance. In my understanding, since TBO implements IB, it automatically implements IA. But why does Supports(), QueryInterface(), GetInterfaceEntry() return false?

How do I query if TBO implements IA directly OR indirectly, i.e. by implementing a superset of IA? I need both, a static class function like GetInterfaceEntry and a dynamic object reference variant like QueryInterface.

解决方案

This is a known quirk of Delphi. Even though IB inherits from IA, TBO must explicitly specify both IA and IB in order for Supports() to retrieve both interfaces.

TBO = class(TInterfacedObject, IA, IB)

I forget the technical reason for this. Something to do with a limitation in how the compiler generates the interface table for TBO. It does not automatically include inherited interfaces.

这篇关于如何检查类是否实现了一个接口,遵守超集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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