使用具有通用接口类型的 Supports() 函数 [英] Use of Supports() function with generic interface type

查看:36
本文介绍了使用具有通用接口类型的 Supports() 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚在 Delphi 2009 中第一次尝试使用泛型,但对如何使用泛型类型作为 Supports 函数的输入感到困惑,该函数用于查看对象是否实现了给定的接口.我创建了一个小样本来说明问题.

I just tried my first use of generics in Delphi 2009 and am perplexed on how to use a generic type as the input to the Supports function used to see if an object implements a given interface. I've created a small sample illustrating the problem.

给定以下类型和效用函数:

Given the following types and utility function:

IMyInterface = interface
['{60F37191-5B95-45BC-8C14-76633826889E}']
end;

TMyObject = class(TInterfacedObject, IMyInterface)
end;

class function TFunctions.GetInterface<T>(myObject: TObject): T;
var
  specificInterface: T;
begin
  // This would compile, but looses the generic capability
  //Supports(myObject, IMyInterface, specificInterface);

  // This results in compile errors
  Supports(myObject, T, specificInterface);

  result := specificInterface;
end;

以及以下代码片段:

class procedure TFunctions.Test;
var
  myObject: TMyObject;
  myInterface: IMyInterface;
begin
  myObject := TMyObject.Create;

  myInterface := GetInterface<IMyInterface>(myObject);
end;

我预计不会有任何问题,但出现以下编译时错误:

I would expect no problems but I get the following compile time errors:

[DCC 错误] GenericExample.pas(37): E2029 '(' 预期但 ',' 找到[DCC 错误] GenericExample.pas(37):应为 E2014 语句,但发现类型为T"的表达式

[DCC Error] GenericExample.pas(37): E2029 '(' expected but ',' found [DCC Error] GenericExample.pas(37): E2014 Statement expected, but expression of type 'T' found

我不确定编译器希望我用 T 作为函数的实际参数做什么.

I'm not sure what the compiler is expecting me to do with the T when used as the actual argument to the function.

我已经搜索了很多,但无法破解这个.我的一部分怀疑,如果我能理解在编译期间接口名称如何转换为 IID:TGUID 类型,当使用具体的接口名称时,我可以取得一些进展,但我也回避了这一点.

I've searched around quite a bit and haven't been able to crack this one. A part of me suspects that if I could understand how an interface name gets converted to the IID: TGUID type during compilation, when using a concrete interface name, I could make some headway, but that has evaded me also.

非常感谢任何帮助.

推荐答案

不能保证 T 有与之关联的 GUID,并且语言中没有办法在类型参数上编写约束来保证.

There is no guarantee that T has a GUID associated with it, and there is no means in the language to write a constraint on the type parameter to make that guarantee.

接口名称通过编译器在符号表中查找名称,得到编译器表示接口的数据结构,并检查GUID的对应字段,转换为GUID.但是泛型不像 C++ 模板;它们需要经过编译和类型检查,并且已知可用于任何有效的类型参数,这意味着在其声明中限制类型参数.

The interface name is converted into a GUID by the compiler looking up the name in the symbol table, getting the compiler's data structure representing the interface, and checking the corresponding field for the GUID. But generics are not like C++ templates; they need to be compiled and type-checked and known to work for any valid type parameter, and that means constraining the type parameter in its declaration.

您可以使用 RTTI 获取 GUID(首先检查 T 确实代表一个接口)和类似 GetTypeData(TypeInfo(T))^.Guid 并将 GUID 传递给 Supports 那样.

You can get the GUID using RTTI (first checking that T does indeed represent an interface) with something like GetTypeData(TypeInfo(T))^.Guid and pass the GUID to Supports that way.

这篇关于使用具有通用接口类型的 Supports() 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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