Delphi指针,包含泛型类型的类的调用函数
我有一个Delphi类,它包含这样一个泛型Delphi指针,包含泛型类型的类的调用函数,delphi,generics,Delphi,Generics,我有一个Delphi类,它包含这样一个泛型 type TObjectList<T:class, constructor> = class private FList: Tlist<T>; public function CreateItem : T; function Next : T; . . . end; 类型 TObjectList=类 私有的 FList:Tlist; 平民的 函数CreateItem:T; 函
type
TObjectList<T:class, constructor> = class
private
FList: Tlist<T>;
public
function CreateItem : T;
function Next : T;
.
.
.
end;
类型
TObjectList=类
私有的
FList:Tlist;
平民的
函数CreateItem:T;
函数Next:T;
.
.
.
终止
在我项目的另一部分中,我需要使用不带T的TObjectList,就像这样
type
NavControl = class
_plist:Pointer;
public
constructor Create<T:class,constructor>(list:TObjectList<T>);
end
类型
导航控制=类
_plist:指针;
平民的
构造函数创建(列表:TObjectList);
终止
如何将列表影响到
\u plist
,以及如何从\u plist
调用CreateItem
,下一步
?如果要使用泛型类型,需要将正在使用的泛型类型存储在某处
但是,没有可以保存类型参数的类型。您要么必须将T
的类型存储在类本身中,要么找出其他方法
您有两个选择:
推荐选项
重新声明NavControl
如下:
type
TNavControl<T:class, constructor> = class
private
_Plist: TObjectList<T>;
public
constructor Create(const List: TObjectList<T>);
通用和旧skool混搭-不推荐使用-
另一种方法是认识到T
是一个对象,因此您可以将其类存储在TClass类型的变量中,但是为了做到这一点,您必须在构造函数中进行一些创新
type
TNavControl = class
private
_PList: TObjectList<TObject>;
ClassOfT: TClass;
constructor TNavControl.Create<T:class, constructor>(const List: TObjectList<T>);
var
Dummy: T;
begin
Dummy:= T.Create;
try
ClassOfT:= TObject(Dummy).ClassType;
finally
Dummy.Free;
end;
end;
现在如果你打电话
var
A: TMyClass2;
B: TMyClass;
C: TNavControl;
A:= TMyClass.Create('test');
C:= TNavControl.Create(A.ClassType);
B:= C.NewItem('test2'); //Creates a TMyClass2
泛型在处理类时没有多大用处,最好使用…
类和虚拟构造函数。这也允许使用具有参数的构造函数,而一般解决方案不满足这些参数。
只需确保构造函数参数始终保持不变
有关更多信息,请参见此答案:为什么
\u plist
是非类型的指针?它需要是一个TObjetcList
,这将需要将泛型参数从Create
移动到NavControl
。如果您将justCreate
设置为Generic,您将无法稍后键入cast\u plist
,因为您不知道传递给Create
的t
是什么。NavControl是singlton???,因此,我不能使用Generic,所有列表都需要控制(添加、删除,…)仅从一个具有激活的corse witch used list的位置开始。显示的代码中没有任何内容将NavControl
限制为单例。但即使是单身,这也不会改变我所说的。如果将\u plist
保留为指针
,则必须在需要访问其成员时键入cast,如果不知道它是什么类型,则无法键入cast,并且无法使用传递给Create
的t
,因为它仅为Create
而存在。你需要重新思考你的方法。特别是如果NavControl
是一个单例,没有理由不能将t
参数移到NavControl
而不是Create
,那么就可以给\u plist
一个合适的类型。我需要尽量避免将TNavControl设置为泛型,其他部分、接口似乎都是完美的选择(TObjectList实现了一些接口)并且我所有的代码都使用该接口调用TNavControl(是singlton)。很抱歉没有很好地描述我的问题。@webmaster:那么请你的问题来说明你想如何使用NavControl
,以便有人能告诉你如何正确地使用它,或者更好地使用它。
type
TMyClass = class(TControl)
...
constructor Create(const param: string = ''); virtual; <<!!!!
end;
TMyClass2 = class(TMyClass)
constructor Create(const param: string = ''); override <<!!
end;
TMyClassClass = class of TMyClass;
TNavControl = class
private
FMyClassClass = TMyClassClass;
FPList = TObjectList; //non-generic version
public
constructor Create(const ClassType: TMyClassClass);
function TNavControl.NewItem(const param: string = ''): TMyClass;
begin
Result:= FMyClassClass.Create(param); //Will create a TMyClass2 or 3
//Or whatever type you fed into the constructor.
end;
var
A: TMyClass2;
B: TMyClass;
C: TNavControl;
A:= TMyClass.Create('test');
C:= TNavControl.Create(A.ClassType);
B:= C.NewItem('test2'); //Creates a TMyClass2