我不确定这是否可以在Delphi中使用。我环顾四周,似乎无法找到答案(示例或不当行为,这是不可能的):
我有一个通用列表类,我想创建一个泛型类型的实例。例如:
type
TTypeA = class(TObject);
procedure Test;
var
MyList: TobjectList<TTypeA>;
NewListObject: TTypeA;
begin
MyList := TObjectList<TTypeA>.Create;
NewListObject := MyList.xxx //what to put on the xxx
end;
是否可以创建一个函数xxx来创建TTypeA类型的新对象?
@jeroen:谢谢你的回答。但是,我在问题中忘了一个重要的细节:
我希望这段代码也适用于任何其他类型,因此没有关于TObjectList的类型T的先验知识。我可能会创建以下列表:
MyList: TObjectList<TCar>;
MyList: TObjectList<TBike>;
在不知道MyList是否包含TCar或TBike(都来自相同的基类和相同的构造函数)的情况下,我想向MyList添加一个新项目。
根据Uwe Raabe的建议,我遇到了下一个问题:
我将课程修改为
TMyObjectList<T:class, constructor> = class(TMyBaseObjectList<T>)
其中TMyBaseObjectList定义为
TMyBaseObjectList<T:TMyBaseObject> = class(TObjectList)
现在我收到一个错误: 类型参数“T”与类型“T:TMyBaseObject”
不兼容答案 0 :(得分:3)
如你所知,你为什么不写
NewListObject := TTypeA.Create;
MyList.Add(NewListObject);
这是在这里做的自然方式。 (我刚刚通过Jeroen的类似回答通知)
如果您希望容器创建对象,则必须创建一个后代类,该类可以更多地了解创建实例的泛型类型。构造函数约束可能对此有所帮助。
type
TMyObjectList<T:class, constructor> = class(TObjectList<T>)
public
function NewObject: T;
end;
function TMyObjectList<T>.NewObject: T;
begin
result := T.Create;
end;
注意:这仅在实际类型具有名为 Create 的无参数构造函数时才有效。
更新:这将有助于
TMyObjectList<T:constructor, TMyBaseObject> = class(TObjectList<T>)
public
function NewObj: T;
end;
答案 1 :(得分:0)
在xxx
处,输入:TTypeA.Create(...);
where ...是创建构造函数的参数。
答案 2 :(得分:0)
我的猜测是不可能的。除非您的列表中有项目,否则您可以这样做:
NewListObject := MyList[0].ClassType.NewInstance as TTypeA;
答案 3 :(得分:0)
或者,您可以从TCollection
下载列表类,从TCollectionItem
下载您的项目,并将其用作基类。他们已经建成了所有的管道。要使用您的示例:
type
TTypeA = class(TCollectionItem);
procedure Test;
var
MyList: TCollection;
NewListObject: TTypeA;
begin
MyList := TCollection.Create(TTypeA);
NewListObject := MyList.Add;
end;
编辑:我知道,它不是使用Generics,但您可以查看TCollection和TCollectionItem以获取更多设计思路,特别是在涉及所有权,通知和生命周期管理时。
答案 4 :(得分:0)
据我所知,你只能在泛型类的泛型类中使用无参数构造函数。
此问题的一个“解决方法”是使用匿名方法创建对象,但这意味着您需要创建许多方法。
至于另一个问题......
TMyObjectList<T:class, constructor> = class(TMyBaseObjectList<T>)
TMyBaseObjectList<T:TMyBaseObject> = class(TObjectList)
我相信正确的宣言是
TMyObjectList<T:TMyBaseObject, constructor> = class(TMyBaseObjectList<T>)
TMyBaseObjectList<T:TMyBaseObject> = class(TObjectList)
TMyBaseObjectList已经强制T为TMyBaseObject类型。如果在TMyObjectList中声明T:class,它将不满足TMyBaseObjectList的要求。