我有一个包含类似通用的Delphi类
type
TObjectList<T:class, constructor> = class
private
FList: Tlist<T>;
public
function CreateItem : T;
function Next : T;
.
.
.
end;
在我的项目的另一部分中,我需要使用没有T的TObjectList,就像那样
type
NavControl = class
_plist:Pointer;
public
constructor Create<T:class,constructor>(list:TObjectList<T>);
end
如何影响_plist
的列表,以及如何从CreateItem
致电Next
,_plist
?
答案 0 :(得分:2)
如果您想使用通用类型,则需要存储您在某处使用的通用类型。
但是没有可以容纳type parameter
的类型。您必须在类本身中存储T
的类型,或者找出其他一些做事方式。
您有两种选择:
推荐选项
Redeclare NavControl
就像这样:
type
TNavControl<T:class, constructor> = class
private
_Plist: TObjectList<T>;
public
constructor Create(const List: TObjectList<T>);
在T
中创建NavControl
的新实例非常简单:
begin
NewItem:= T.Create;
.....
通用和旧图书馆的混搭 - 不推荐 -
另一种方法是识别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;
您现在必须使用TClass
引用来实例化对象,但TClass
需要通用约束不会--Oops - 的虚拟构造函数。
我的推荐
就个人而言,我不会在这里打扰泛型
你知道你想要一个班级,你知道你需要一个构造函数
只要构造函数是虚拟的,使用此方法就可以使用带或不带参数的构造函数
只需将对象列表限制为您控制并使用它的合理子类。
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
泛型在使用类时非常有用,最好使用class of ...
和虚拟构造函数。
这也允许使用带有参数的构造函数,通用解决方案不能满足这些参数
只需确保始终保持构造函数参数相同。
有关详细信息,请参阅此答案:https://stackoverflow.com/a/758715/650492