就像在Java Collection接口(interface)定义中一样,我想创建一个列表类型,其中addItems/removeItems获取一个验证器参数来在添加/删除之前过滤项目。 非常必要的代码片段:
IListItemValidator<T> = interface
['{79E22756-9EC5-40C5-A958-0AA04F6F1A79}']
function validateItem( item_ : T ) : boolean;
end;
IList<T> = interface
['{DC051351-D7B7-48BB-984E-A0D9978A02C1}']
function getCount : cardinal;
function itemAt( ndx_ : cardinal ) : T;
function addItems( list_ : ILIst<T>; validator_ : IListItemValidator<T> = NIL );
end;
TList<T> = class ( TInterfacedObject, IList<T> )
private
fCount : cardinal;
fItems : TArray<T>;
public
function getCount : cardinal;
function getItemAt( ndx_ : cardinal ) : T;
function addItems( list_ : ILIst<T>; validator_ : IListItemValidator<T> = NIL );
function TList<T>.getCount : cardinal;
begin
result := fCount;
end;
function TList<T>.getItemAt( ndx_ : cardinal ) : T;
begin
if ( ndx_ < fCount ) then
result := fItems[ndx_]
else
;//raise...
end;
function TList<T>.addItems( list_ : ILIst<T>; validator_ : IListItemValidator<T> = NIL );
var
i : integer;
item : T;
begin
if ( list_ <> NIL ) then
for i := 0 to list_.getCount-1 do
begin
item := list_.getItemAt( i );
if ( ( validator_ = NIL ) or validator_.validateItem( item ) ) then
//addItem
else
result := -1;
end
else
;//raise...
end;
如果我想添加值大于 4 的项目,我应该如何定义 TListItemValidator? (例如) 匿名函数参数化重载的 addItems/removeItems 方法工作正常,但如何创建基于通用接口(interface)的解决方案?
没有一种变体可以编译:
第一个(很明显。T与System.Integer不兼容)
TListItemValidator<T> = class ( TInterfacedObject, IListItemValidator<T> )
public
function validateItem( item_ : T ) : boolean;
end;
function TListItemValidator<T>.validateItem( item_ : T ) : boolean;
begin
result := item_ > 5;
end;
第二个(我尝试直接使用整数):
TListItemValidator<integer> = class ( TInterfacedObject, IListItemValidator<integer> )
public
function validateItem( item_ : integer ) : boolean;
end;
function TListItemValidator<integer>.validateItem( item_ : integer ) : boolean;
begin
result := item_ > 5;
end;
编译错误:
E2015 运算符不适用于此操作数类型
我明白原因:“TListItemValidator”中的“整数”就像第一个示例中的“T”,只是类型占位符。但是我怎样才能为整数值创建一个有效的验证器呢?
最佳答案
您的两个变体实际上含义相同:
TListItemValidator<T> = class ( TInterfacedObject, IListItemValidator<T> )
public
function validateItem( item_ : T ) : boolean;
end;
TListItemValidator<integer> = class ( TInterfacedObject, IListItemValidator<integer> )
public
function validateItem( item_ : integer ) : boolean;
end;
它们都是泛型类型。唯一的区别是外观,即通用参数的名称。您可能已将泛型参数命名为 integer
,但这只是一个名称,在这种情况下。
您需要的是一个实现 IListItemValidator<integer>
的具体类。像这样的事情:
type
TIntegerListItemValidator = class ( TInterfacedObject, IListItemValidator<integer> )
function validateItem( item_ : integer ) : boolean;
end;
function TIntegerListItemValidator.validateItem( item_ : integer ) : boolean;
begin
result := item_ > 4;
end;
关于delphi - E2015 运算符不适用于此操作数类型 (Delphi 10.2),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56806972/