通用接口如何引用指向其类型参数的指针?
How can a generic interface refer to a pointer to its type parameter?
简而言之,我希望能够做这样的事情(其中 T 通常是一条记录)
interface
ITable<T> = interface
...
other methods
...
function Append: ^T;
end;
但是正如我们在 a question about declaring pointers based on generic types 中看到的,Delphi 不允许 ^T
构造。如果允许的话,我可以做这样的事情:
var
myrec: PMyRec;
myTable: ITable<TMyRec>;
begin
myTable := TableFactory.Build(TMyRec);
myRec := myTable.Append;
myRec.FieldA := 'Test';
.. Do stuff with myTable containing myRec
end;
我想这样做的原因是,我有很多现有的代码都是以这种方式编写的,而不是建立一个记录然后调用一个接受构建记录的过程,比如 MyTable.Add(MyRec)
,这是更像Delphi的方式。
链接问题的解决方案是在通用 class 中使用内部 type
语句,但通用 接口 不允许 type
语句。
为了解决这个问题,我想我可以使用像 Spring4D 接口集合这样的东西,使用通用记录到 return 指针,如下所示:
ListRec<T> = record
type
P = ^T;
private
InternalList = IList<T>;
public
... exposed list functions
function Append: PT;
end;
function ListRec<T>.Append: PT;
var
index: integer;
TempT: TMyRec;
begin
index := InternalList.add(TempT);
result := @InternalList.Items[index];
end;
毕竟,我的问题是:有没有更简单的方法来实现我的 objective 还是我把它过度复杂化了?是否有任何明显的缺点(除了使用指针的标准风险)?如果没有别的,我理想情况下更喜欢纯接口解决方案以实现可测试性。
在理想情况下,您可以直接声明通用指针类型:
type
P<T> = ^T;
但是语言不允许这样做。您可以声明通用指针类型,但前提是它们包含在另一种类型中。例如:
type
PointerTo<T> = record
type
P = ^T;
end;
现在你的界面可以是:
type
ITable<T> = interface
function Append: PointerTo<T>.P;
end;
坦率地说,在我看来,这是相当蹩脚的。
简而言之,我希望能够做这样的事情(其中 T 通常是一条记录)
interface
ITable<T> = interface
...
other methods
...
function Append: ^T;
end;
但是正如我们在 a question about declaring pointers based on generic types 中看到的,Delphi 不允许 ^T
构造。如果允许的话,我可以做这样的事情:
var
myrec: PMyRec;
myTable: ITable<TMyRec>;
begin
myTable := TableFactory.Build(TMyRec);
myRec := myTable.Append;
myRec.FieldA := 'Test';
.. Do stuff with myTable containing myRec
end;
我想这样做的原因是,我有很多现有的代码都是以这种方式编写的,而不是建立一个记录然后调用一个接受构建记录的过程,比如 MyTable.Add(MyRec)
,这是更像Delphi的方式。
链接问题的解决方案是在通用 class 中使用内部 type
语句,但通用 接口 不允许 type
语句。
为了解决这个问题,我想我可以使用像 Spring4D 接口集合这样的东西,使用通用记录到 return 指针,如下所示:
ListRec<T> = record
type
P = ^T;
private
InternalList = IList<T>;
public
... exposed list functions
function Append: PT;
end;
function ListRec<T>.Append: PT;
var
index: integer;
TempT: TMyRec;
begin
index := InternalList.add(TempT);
result := @InternalList.Items[index];
end;
毕竟,我的问题是:有没有更简单的方法来实现我的 objective 还是我把它过度复杂化了?是否有任何明显的缺点(除了使用指针的标准风险)?如果没有别的,我理想情况下更喜欢纯接口解决方案以实现可测试性。
在理想情况下,您可以直接声明通用指针类型:
type
P<T> = ^T;
但是语言不允许这样做。您可以声明通用指针类型,但前提是它们包含在另一种类型中。例如:
type
PointerTo<T> = record
type
P = ^T;
end;
现在你的界面可以是:
type
ITable<T> = interface
function Append: PointerTo<T>.P;
end;
坦率地说,在我看来,这是相当蹩脚的。