gpt4 book ai didi

Delphi - 使用泛型的接口(interface)继承

转载 作者:行者123 更新时间:2023-12-03 14:52:27 24 4
gpt4 key购买 nike

我目前遇到了编译错误,我们公司没有人可以提供帮助,遗憾的是我没有找到 SO 或 google 的正确搜索模式。

作为代码,我使用 2 个继承的接口(interface)和 2 个继承的类。以下代码重现了该错误:

program Project22;

{$APPTYPE CONSOLE}
type
IStorageObject = interface(IInterface)
end;
TObjectStorage<T: IStorageObject> = class(TObject)
end;
IKeyStorageObject<TKey> = interface(IStorageObject)
end;
TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>)
end;
TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>)
end;
begin
TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create;
end.

“TKeyObjectStorage”的编译器错误是:

[DCC Error] Project22.dpr(11): E2514 Type parameter 'T' must support interface 'IStorageObject'

我认为编译器没有正确识别“TKeyObjectStorage”类的参数 T。它应该是正确的,因为所需的类型“IKeyStorageObject”具有父类型 IStorageObject。

为什么这不起作用?我究竟做错了什么?这在 Delphi 中不可能吗?

最佳答案

更新

原来的问题有一个我发现的问题(见下文)。然而,我描述的修复对于 XE3 及更高版本来说很好,但下面的程序不能在 XE2 中编译。因此我得出结论,这是一个 XE2 泛型编译器错误。

无论如何,这是Delphi XE2的解决方法:

{$APPTYPE CONSOLE}
type
IStorageObject = interface(IInterface)
end;
TObjectStorage<T: IStorageObject> = class(TObject)
end;
IKeyStorageObject<TKey> = interface(IStorageObject)
end;
TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>, IStorageObject> = class(TObjectStorage<T>)
end;
TImplementingClass<TKey> = class(TInterfacedObject, IStorageObject, IKeyStorageObject<TKey>)
end;
begin
TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create;
end.
<小时/>

原始答案

如果您能提供一个显示编译器错误的完整程序,那就更好了。您需要尝试实例化一个对象才能看到该错误。

但是,我想我已经重现了你的问题。所以我认为问题在于这段代码:

TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = ...

将通用约束应用于TKeyT。现在,显然您只想将约束应用于 T,因此您需要编写:

TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = ...

这是一个根据 Delphi XE3 中的更改进行编译的简短程序:

{$APPTYPE CONSOLE}
type
IStorageObject = interface(IInterface)
end;
TObjectStorage<T: IStorageObject> = class(TObject)
end;
IKeyStorageObject<TKey> = interface(IStorageObject)
end;
TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>)
end;
TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>)
end;
begin
TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create;
end.

这是一个非常细微的差别,将逗号更改为分号。使用重要的标点符号进行编程从来都不是一件有趣的事情。也就是说,您熟悉形式参数列表中逗号和分号之间的区别,因此看到这里绘制的相同区别应该不会太令人惊讶。

documentation确实涵盖了这一点,请注意:

Multiple Type Parameters

When you specify constraints, you separate multiple type parameters by semicolons, as you do with a parameter list declaration:

type
TFoo<T: ISerializable; V: IComparable>

Like parameter declarations, multiple type parameters can be grouped together in a comma list to bind to the same constraints:

type
TFoo<S, U: ISerializable> ...

In the example above, S and U are both bound to the ISerializable constraint.

关于Delphi - 使用泛型的接口(interface)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19682057/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com