Delphi 如何使泛型对象列表从特定基类开始工作? TMyDataList=class(TObjectList) 公众的 构造函数创建; 程序上传(db:TDataSet); 结束;

Delphi 如何使泛型对象列表从特定基类开始工作? TMyDataList=class(TObjectList) 公众的 构造函数创建; 程序上传(db:TDataSet); 结束;,delphi,generics,delphi-2009,Delphi,Generics,Delphi 2009,我在一篇博客文章(我不记得现在在哪里)中读到,这是一种使用泛型对象的特定基类型声明基于泛型的类的方法。编译器会很好地接受它。但当我尝试使用它时,它决定不合作 TMyDataList<T: TBaseDatafile, constructor> = class(TObjectList<TBaseDatafile>) public constructor Create; procedure upload(db: TDataSet);

我在一篇博客文章(我不记得现在在哪里)中读到,这是一种使用泛型对象的特定基类型声明基于泛型的类的方法。编译器会很好地接受它。但当我尝试使用它时,它决定不合作

   TMyDataList<T: TBaseDatafile, constructor> = class(TObjectList<TBaseDatafile>)
   public
      constructor Create;
      procedure upload(db: TDataSet);
   end;
类型
tDescendatList=tMyCatalist;
这给了我一个编译器错误

[DCC错误]my_database.pas(1145):E2010不兼容类型:“tdescendatdatafile”和“TBaseDatafile”

事实上,1145甚至不是一条有效的线。所讨论的文件以#1142结尾,它所抱怨的类型声明位于#20行。这让我怀疑这是否是编译器的小故障。或者我只是不太懂语法?有人知道如何让这一切顺利吗


编辑:吉姆在试用时指出它编译得很好。更多信息:我在同一个单元中声明了基本数据文件类型和泛型列表,而TDESCENDATDATAFILE在第二个单元中,TDESCENDATLIST在第三个单元中定义。我已经在D2009的编译器中发现并报告了一个bug,涉及泛型在多个单元之间扭曲类型。这可能是相关的。有人能证实这一点吗?

TObjectList的定义是:

TObjectList=class(TList)
所以你喜欢这样做:

TObjectList<T: class> = class(TList<T>)
TMyDataList=class(TObjectList)
不幸的是,这行不通。幸运的是:

TMyDataList<T: TBaseDatafile> = class(TObjectList<T>)
TMyDataList=class(TObjectList)
工作,但这可能不是你想要的。因为它不会利用类类型。我真的认为类说明符在这里有点奇怪。(托宾应该避免这些问题)。但这对你没有帮助

同样,以下工作:

TMyDataList<T: class> = class(TObjectList<T>)
TBaseDataFile=class
结束;
tdescendatdatafile=class(TBaseDataFile)
结束;
TMyDataList=class(TObjectList)
公众的
构造函数创建;
结束;
您确定TDESCENDATDATAFILE继承自TBaseDataFile吗

在过去,(读turbo-pascal)有时行号会因为看不见的字符而出错。但我不认为这仍然有效。

当tdescendatdatafile从TBaseDataFile中派生出来时,它可以在我的机器上正常工作。检查您的类层次结构


如果我更改TDESCENDATDATAFILE的祖先,那么我会得到相同的错误消息,它会给我正确的行号。如果编译器给了你错误的行号,那么关闭项目,重新打开它并进行完整的构建。

使用C#,你将直观地掌握正确的语法:-Pha你试过制作精简的测试用例吗?也许是代码中的其他东西掩盖了这个问题。迈赫达德:我对此深表怀疑。每次都使用非常不直观的语法是我尽可能避免使用整个C系列的主要原因。@Mason:作为一名Delphi开发人员,我发现C#与Delphi pascal的共享量与C#的共享量一样多(或更多)。考虑到以前支持Delphi,现在支持C#的架构师,这可能并不令人感到意外。所以,我不认为用同一个画笔画C和C是有意义的。@Merhdad:C只有在为.NET开发时才是一个替代品,即使在那时也有Delphi Prism。当你为Win32开发的时候,除了Delphi之外没有其他的选择,IMHO。你的“工作”示例几乎就是我设置它的方式。问题是,我无法创建任何填充类型的列表的实际实例。(是的,我非常确定继承性。)如果它“几乎”与您设置的完全相同,那么请将其设置为完全相同,然后查看它是否有效。层次结构是正确的。重新启动和重建没有帮助。隐马尔可夫模型。。。试试这个:在一个单元中声明TMyDataList和TBaseDatafile,在另一个单元中声明tdescendatdatafile,在第三个单元中声明tdescendatlist。我已经发现了一个带有泛型和多个单元的bug。这可能是另一个。
TMyDataList<T: class> = class(TObjectList<T>)
  TBaseDataFile = class
  end;

  TDescendantDatafile = class (TBaseDataFile)
  end;

  TMyDataList<T: TBaseDataFile> = class(TObjectList<TBaseDataFile>)
  public
    constructor Create;
  end;