就像Java Collection接口定义一样,我想创建一个列表类型,其中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方法工作正常,但是如何创建基于通用接口的解决方案?
没有一个版本可以编译:
第一个(很明显。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 Operator not applicable to this operand type
我理解原因:'TListItemValidator'中的'integer'就像第一个示例中的'T'一样,只是类型占位符。但是如何为整数值创建一个有效的验证器?
答案 0 :(得分:3)
您的两个变体实际上含义相同:
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;
答案 1 :(得分:2)
好。我在David发表评论的同时找到了解决方案。 我修改了验证器定义:
IListItemValidator = interface
[...]
function validateItem( const item_ ) : boolean;
end;
TIntegerListItemValidator = class ( TInterfacedObject, IListItemValidator )
function validateItem( const item_ ) : boolean;
end;
function TIntegerListItemValidator.validateItem( const item_ ) : boolean;
begin
result := integer( item_ ) > 4;
end;