如何使通用对象列表从特定基类开始工作?

时间:2021-07-31 20:14:33
   TMyDataList<T: TBaseDatafile, constructor> = class(TObjectList<TBaseDatafile>)
   public
      constructor Create;
      procedure upload(db: TDataSet);
   end;

I read in a blog post (I don't remember where now) that this is the way to declare a generic-based class with a specific base type for the generic object. And the compiler will accept it just fine. But when I try to use it, it decides not to cooperate.

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

type
   TDescendantList = TMyDataList<TDescendantDatafile>;

This gives me a compiler error.

这给了我一个编译器错误。

[DCC Error] my_database.pas(1145): E2010 Incompatible types: 'TDescendantDatafile' and 'TBaseDatafile'

[DCC错误] my_database.pas(1145):E2010不兼容的类型:'TDescendantDatafile'和'TBaseDatafile'

Thing is, 1145 isn't even a valid line. The file in question ends at #1142, and the type declaration that it's complaining about is on line #20. This makes me wonder if it's a compiler glitch. Or do I just not quite have the syntax right? Does anyone know a way to make this work?

事实是,1145甚至不是一个有效的线。有问题的文件在#1142结束,它抱怨的类型声明在第20行。这让我想知道它是否是一个编译器故障。或者我只是没有正确的语法?有没有人知道如何使这项工作?

EDIT: Jim pointed out that it compiles fine when he tried it. A bit more information: I have the base datafile type and the generic list declared in the same unit, while TDescendantDatafile is in a second unit and TDescendantList is defined in a third one. I've already found and reported one bug in D2009's compiler involving generics screwing up types across multiple units. This may be related. Can anyone confirm this?

编辑:吉姆指出,当他尝试它时编译好。更多信息:我有基本数据文件类型和在同一单元中声明的通用列表,而TDescendantDatafile在第二个单元中,TDescendantList在第三个单元中定义。我已经在D2009的编译器中找到并报告了一个错误,涉及泛型在多个单元中搞乱类型。这可能是相关的。谁能证实这一点?

2 个解决方案

#1


The definition of TObjectList<> is:

TObjectList <>的定义是:

TObjectList<T: class> = class(TList<T>)

So you like to do something like:

所以你喜欢做类似的事情:

TMyDataList<T: TBaseDatafile> = class(TObjectList<T>)

Unfortunately, that won't work. Luckily:

不幸的是,这不会奏效。幸运的是:

TMyDataList<T: class> = class(TObjectList<T>)

Works, but that is probably not what you want. Because it will not take advantage of the class type. I really think the class specifier is a bit strange here. (TObject should have avoided the problems). But that's no help for you.

工作,但这可能不是你想要的。因为它不会利用类类型。我真的认为类说明符在这里有点奇怪。 (TObject应该避免这些问题)。但这对你没有帮助。

Then again, the following works:

然后,以下工作:

  TBaseDataFile = class
  end;

  TDescendantDatafile = class (TBaseDataFile)
  end;

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

Are you sure TDescendantDataFile inherits from TBaseDataFile?

你确定TDescendantDataFile继承自TBaseDataFile吗?

In the old days, (read turbo pascal) sometimes the line numbers where wrong because of invisible characters. But I don't think that is still valid.

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

#2


When TDescendantDatafile descends from TBaseDataFile it works fine on my machine. Check your class hierarchy.

当TDescendantDatafile从TBaseDataFile下降时,它在我的机器上正常工作。检查您的类层次结构。

If I change the ancestor of TDescendantDatafile then I get that same error message, and it gives my the right line numbers. If you the compiler is giving you the wrong line numbers then close the project, reopen it and do a full build.

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

#1


The definition of TObjectList<> is:

TObjectList <>的定义是:

TObjectList<T: class> = class(TList<T>)

So you like to do something like:

所以你喜欢做类似的事情:

TMyDataList<T: TBaseDatafile> = class(TObjectList<T>)

Unfortunately, that won't work. Luckily:

不幸的是,这不会奏效。幸运的是:

TMyDataList<T: class> = class(TObjectList<T>)

Works, but that is probably not what you want. Because it will not take advantage of the class type. I really think the class specifier is a bit strange here. (TObject should have avoided the problems). But that's no help for you.

工作,但这可能不是你想要的。因为它不会利用类类型。我真的认为类说明符在这里有点奇怪。 (TObject应该避免这些问题)。但这对你没有帮助。

Then again, the following works:

然后,以下工作:

  TBaseDataFile = class
  end;

  TDescendantDatafile = class (TBaseDataFile)
  end;

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

Are you sure TDescendantDataFile inherits from TBaseDataFile?

你确定TDescendantDataFile继承自TBaseDataFile吗?

In the old days, (read turbo pascal) sometimes the line numbers where wrong because of invisible characters. But I don't think that is still valid.

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

#2


When TDescendantDatafile descends from TBaseDataFile it works fine on my machine. Check your class hierarchy.

当TDescendantDatafile从TBaseDataFile下降时,它在我的机器上正常工作。检查您的类层次结构。

If I change the ancestor of TDescendantDatafile then I get that same error message, and it gives my the right line numbers. If you the compiler is giving you the wrong line numbers then close the project, reopen it and do a full build.

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