繁体   English   中英

如何传递TComparer <T> 类到Delphi中的泛型类型?

[英]How to pass a TComparer<T> class to a generic type in Delphi?

我想创建一个具有一些功能的通用记录,包括搜索功能。 要执行此搜索,我想传递一个自定义Comparer来比较项目。 如果它是一个类,我可以在构造函数中传递它,但我想使用一个记录来避免创建或释放它。 所以,我没有构造函数初始化Comparer。

然后我决定像Type参数一样传递Comparer类,当我需要比较器时,使用TComparer.Default创建比较器的实例。

好吧,这是代码:

TMyArray<T,C: TComparer<T>> = record
  FComparer: IComparer<T>;
  Items: TArray<T>;

  function Contains<AItem: T>: Boolean;
end;

当我尝试以这种方式使用它时出现问题:

TMyRecord = record
  Score: Real;
  A: string;
  B: string;
end;

TMyRecordComparer = class(TComparer<TMyRecord>)
  function Compare(Left, Right: TMyRecord): Integer;
end;

TMyRecordArray = TMyArray<TMyRecord, TMyRecordComparer>;  

使用这最后一个声明,我收到此错误:E2515类型参数'T'与类型'System.Generics.Defaults.TComparer \\'不兼容。

不知道如何解决这个问题?

虽然David的答案解决了编译错误的问题,但实际上我会使用不同的约束:

TMyArray<T; C: class, constructor, IComparer<T>> = record

这意味着C必须是具有无参数构造函数的类,并实现IComparer<T>接口。 这样可以放松约束,因为您不必从System.Generics.Collections.TComparer<T>继承比较器,而只需实现所需的IComparer<T>接口。

另外,fwiw,在您的问题中发布的代码,您将收到W1010警告,这意味着您缺少对TMyRecordComparer.Compare方法(及其缺少的const )的覆盖。 如果从TComparer<T>继承, TComparer<T>因为它使用虚拟抽象方法实现IComparer<T>

您使用.Default想法也不会起作用,因为它为类型T的比较器创建了一个默认实现。 但是您想使用您指定的自定义。

因此,根据我在上面写的约束,你可以做这样的事情(天真的非线程安全实现):

function TMyArray<T, C>.Contains<AItem>: Boolean;
begin
  if FComparer = nil then
    FComparer := C.Create;
  // ....
end;

最后但并非最不重要的是,我不确定您的Contains方法是否正确 - 您编写它的方式表明您要检查您的数组是否包含类型为AItem的类型为T或子类型的元素(或者如果T为一个接口类型,实现T ) - 我猜你想写

function Contains(AItem: T): Boolean;

问题是约束的语法:

TMyArray<T,C: TComparer<T>>

这将TC都限制为TComparer<T>

相反,你需要这个:

TMyArray<T; C: TComparer<T>>

文档提供了各种语法选项的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM