Delphi中通用持有记录中的相等运算符

Posted

技术标签:

【中文标题】Delphi中通用持有记录中的相等运算符【英文标题】:Equal operator in Generic holding Records in Delphi 【发布时间】:2014-03-19 06:59:51 【问题描述】:

我有一个泛型列表,我想在其中放置一些记录或一些类

TMyList<T> = class
private
  fCount: Cardinal;
  fItems: array of T;
public
  constructor Create(aSize: Integer);
  procedure UpdateItem(const x: T);
end;

但是我不能编译

procedure TMyList<T>.UpdateItem(const x: T);
var
  I: integer;
begin
  for I := 0 to fCount - 1 do
    if fItems[I] = x then begin  // <- error  E2015
    //do update
    break;
  end;
end;

它适用于具有以下声明的类:TMyList&lt;T : class&gt; = class,但它不能再保存记录了。

当然,为了记录,我声明class operator Equal(Left, Right : TMyRecord) : Boolean; 以便MyRecord1 = MyRecord2 可以编译。

【问题讨论】:

【参考方案1】:

使用= 运算符永远无法实现这一点。原因是通用约束不够丰富,无法指定运算符的可用性。您根本不能在泛型操作数上使用= 运算符。

如果将操作数限制为类,则可以这样做,因为类是引用,编译器知道如何比较引用是否相等。基本上,编译器在编译泛型类时需要知道如何生成代码。与 C++ 或 Smalltalk 模板不同,使用泛型,编译器不会等到实例化才编译代码。

如果您想使用自定义比较器,则需要明确提供。我知道,这很令人沮丧。如果您可以使用默认比较器,则可以使用:

TEqualityComparer<T>.Default

【讨论】:

以上是关于Delphi中通用持有记录中的相等运算符的主要内容,如果未能解决你的问题,请参考以下文章

如何模拟Delphi records中的位域

Delphi_03_Delphi_Object_Pascal_基本语法_01

python中的比较运算符

Delphi中的按位补码。 (翻译C#〜运算符)

C#中的运算符重载

JS相等判断中的运算符