我创建了一个自定义TObjectList后代,用于保存基础对象类的子类。它看起来像这样:
interface
TMyDataList<T: TBaseDatafile> = class(TObjectList<TBaseDatafile>)
public
constructor Create;
procedure upload(db: TDataSet);
end;
implementation
constructor TMyDataList<T>.Create;
begin
inherited Create(true);
self.Add(T.Create);
end;
我希望每个新列表都以一个空白对象开头。这很简单,对吧?但编译器不喜欢它。它说:
“无法在类型参数声明中创建没有CONSTRUCTOR约束的新实例” 我只能假设这是与泛型相关的东西。任何人都知道发生了什么以及如何使这个构造函数工作?
答案 0 :(得分:17)
您正尝试通过T
创建T.Create
的实例。这不起作用,因为编译器不知道您的泛型类型具有无参数构造函数(请记住:这不是必需的)。要纠正这个问题,你必须创建一个构造函数约束,如下所示:
<T: constructor>
或者,在您的具体情况下:
<T: TBaseDatafile, constructor>
答案 1 :(得分:2)
快速更新旧问题..
你不需要构造函数约束,也可以使用像这样的RTTI对带有参数的对象执行此操作(使用RTTI或System.RTTI和XE2)
constructor TMyDataList<T>.Create;
var
ctx: TRttiContext;
begin
inherited Create(true);
self.Add(
ctx.
GetType(TClass(T)).
GetMethod('create').
Invoke(TClass(T),[]).AsType<T>
);
end;
如果你有参数,只需像这样添加
constructor TMyDataList<T>.Create;
var
ctx: TRttiContext;
begin
inherited Create(true);
self.Add(
ctx.
GetType(TClass(T)).
GetMethod('create').
Invoke(TClass(T),[TValue.From('Test'),TValue.From(42)]).AsType<T>
);
end;