【发布时间】:2019-07-14 16:56:16
【问题描述】:
我的目标是使用相同的代码创建几个类似的列表(因此我不必多次编写 LoadFromString() 和 LoadFromXML()。
我做了一个 TKeyValueList (和一个 TKeyIntValueList = 类(TKeyValueList
TKeyValueItem<T> = class(TLockObject)
protected
FKey : T;
FValue : Variant;
....... etc
TKeyValueList<T> = class(TLockObject)
protected
FList : TList<TKeyValueItem<T>>;
------ etc
效果很好....
但是当我想创建一个列表来保存通过 TCP/IP(使用我自己的“RESTFUL”协议)发送的数据库记录中的值时,它会失败。
基类:
TDBRecord<IDT, FieldIDT> = class(TKeyValueList<FieldIDT> );
// Any ID type (i.e. Primary key from DB kan be int/string etc)
// Any type of field identifier, e.g. string for field name or my own
// TCommDataType (enumeration like cdtTextID....)
基本列表定义为
TDBRecordList<IDT, FieldIDT> = class(TList<TDBRecord<IDT, FieldIDT>)
然后我定义了一个通用后代以使用 int 主键保存来自数据库的记录,例如 SQL Server "t_TextID int identity primary key not null" 以避免在我当前的项目中包含所有 PKs er int.
TDBIntIDRecord<FieldIDT> = class(TDBRecord<Integer, FieldIDT>);
TDBIntIDRecordList<FieldIDT, T : TDBIntIDRecord<FieldIDT>> = class(TDBRecordList<Integer, FieldIDT, T>);
为了专门化它并避免指定字段名称的类型(这是一个枚举),我做了这个:
TDBCommTypeIDRecord = class(TDBIntIDRecord<TCommDataType>);
TDBCommTypeIDList = class(TDBIntIDRecordList<TCommDataType>)
当我尝试使用单个 TDBRecord 调用方法时,即带有列表项的 TDBCommTypeIDRecord (TDBCommTypeIDList[StringGridItems.Selected]) 我收到编译器错误:
TDBRecord 与 TDBCommTypeIDRecord 不兼容。
根据泛型(和 Marco Cantú)的文档,泛型与具有完全相同的类型名称无关,而是具有相同的类型。
那为什么那部分不起作用????
我试图通过以下方式解决它(即规避问题):
///////////////
TDBRecord<IDT, FieldIDT> = class(TKeyValueList<FieldIDT> );
TDBRecordList<IDT, FieldIDT, T : TDBRecord<IDT, FieldIDT>> = class(TList<T>);
TDBIntIDRecord<FieldIDT> = class(TDBRecord<Integer, FieldIDT>);
TDBIntIDRecordList<FieldIDT, T : TDBIntIDRecord<FieldIDT>> = class(TDBRecordList<Integer, FieldIDT, T>);
///////////////
这给了我一个编译时错误,说 IDT 与 FieldIDT 不兼容。嗯……显然不是! IDT 现在是 Integer 而 FieldIDT 不是(稍后在 TCommDataType 定义的流程中)
但是声明 - TDBRecord 和 - TDBRecordList
我认为应该消除 IDT。
我做错了什么? 我误会了什么?
请帮忙......
问题中描述了我解决此问题的尝试。
问题描述中包含的代码。我可以提供完整的 POC 项目来说明问题。
我会 - 基于文档和 Marco Cantú - 期待我的第一次和第二次尝试编译和运行运行时。相反,我收到了作为问题一部分描述的错误消息。
【问题讨论】:
-
我很确定编译器是正确的,并且您的代码不会被编译。然而,很难看透所有细节。 minimal reproducible example 会有所帮助。
-
谢谢,但目前我更担心的是,我了解到 Google Play 将终止对 32 位应用程序的支持。这对我的项目来说是一个重大打击,因为 Delphi 不能编译到 Android 64 位。如果我仍然使用 Delphi 并且不重写所有内容,我会回来的。
-
您需要帮助解决这两个问题中的哪一个?
标签: delphi generics inheritance