这对我来说有点令人费解,因为我正在开发一个具有几十个接口的单元,这些接口都基于这个基本接口定义:
type
IDataObject = interface(IInterface)
['{B1B3A532-0E7D-4D4A-8BDC-FD652BFC96B9}']
function This: TDataObject;
end;
ISomeObject = interface(IDataObject)
['{7FFA91DE-EF15-4220-A43F-2C53CBF1077D}']
<Blah>
end;
这意味着他们都有一个方法“This”,它返回接口后面的类,有时需要放入列表视图和东西,但对于这个问题,这并不重要,因为我想要一个具有附加功能的泛型类可以应用于任何派生接口。(并且任何派生接口都有自己的 GUID。)这是泛型类:
type
Cast<T: IDataObject> = class(TDataObject)
class function Has(Data: IDataObject): Boolean;
class function Get(Data: IDataObject): T;
end;
看起来不太复杂,使用类方法是因为 Delphi 不支持全局泛型函数,除非它们在一个类中。所以在我的代码中,我想用它Cast<ISomeObject>.Has(SomeObject)
来检查对象是否支持特定的接口。如果可能,该Get()
函数只是将对象作为特定类型返回。所以,接下来的实现:
class function Cast<T>.Get(Data: IDataObject): T;
begin
if (Data.QueryInterface(T, Result) <> S_OK) then
Result := nil;
end;
class function Cast<T>.Has(Data: IDataObject): Boolean;
begin
Result := (Data.QueryInterface(T, Result) = S_OK);
end;
这就是令人讨厌的地方!在我使用的代码的其他地方,if (Source.QueryInterface(ISomeObject, SomeObject) = 0) then ...
它工作得很好。在这些通用方法中,ISomeObject
替换为T
并且应该可以正常工作。但它拒绝编译并给出此错误:
[dcc64 错误] DataInterfaces.pas(684):E2010 不兼容的类型:“TGUID”和“T”
这很烦人。我需要解决这个问题,但如果不深入研究系统单元的接口代码,就找不到合适的解决方案。(这是我被允许在此代码中使用的唯一单位,因为它需要在许多不同的平台上运行!)
错误是正确的,因为 QueryInterface 需要一个 TGUID 作为参数,但它似乎是从 ISomeObject 获取的。那么为什么不来自 T 呢?
我想我在这里尝试做不可能的事情......
更具体一点:Source.QueryInterface(ISomeObject, SomeObject)
无需使用任何其他单元即可正常工作。因此,如果该类型仅限于接口,我希望它可以与泛型类型一起使用。但事实并非如此,我想知道为什么它在接受 ISomeObject 时不接受 T。
你能解释一下为什么它会因泛型类型而不是常规接口类型而失败吗?