Delphi 泛型使用带重载的构造函数?

Delphi 泛型使用带重载的构造函数?,delphi,generics,Delphi,Generics,可能重复: 在我对泛型的冒险中,我现在已经走到了一条死胡同,我希望有人能给我指出隐藏的门:-) 鉴于这种类型 type TMyClass = class private FMyString: String; FMyStringList: TStringList; procedure SetMyString(const Value: String); procedure SetMyStringList(const Value: TStringList);

可能重复:

在我对泛型的冒险中,我现在已经走到了一条死胡同,我希望有人能给我指出隐藏的门:-)

鉴于这种类型

type
  TMyClass = class
  private
    FMyString: String;
    FMyStringList: TStringList;
    procedure SetMyString(const Value: String);
    procedure SetMyStringList(const Value: TStringList);
  public
    constructor Create; overload;
    constructor Create(InitString : String); overload;
    destructor Destroy; override;
    property MyString: String read FMyString write SetMyString;
    property MyStringList : TStringList read FMyStringList write SetMyStringList;
  end;

  TMyClassList<T:TMyClass, constructor> = class(TObjectList<T>)
  public
    constructor Create; overload;
  end;

implementation

{ TMyClass }

constructor TMyClass.Create;
begin
  inherited;
  MyString := '';
  MyStringList := TStringList.Create;
  MyStringList.Add('This');
  MyStringList.Add('is');
  MyStringList.Add('a');
  MyStringList.Add('test.');
end;

constructor TMyClass.Create(InitString: String);
begin
  Create;
  MyString := InitString;
end;
类型
TMyClass=类
私有的
FMyString:字符串;
FMyStringList:TStringList;
过程SetMyString(常量值:String);
程序SetMyStringList(常量值:TStringList);
公众的
构造函数创建;超载;
构造函数创建(InitString:String);超载;
毁灭者毁灭;推翻
属性MyString:字符串读取FMyString写入SetMyString;
属性MyStringList:TStringList read FMyStringList write SetMyStringList;
结束;
TMyClassList=类(TObjectList)
公众的
构造函数创建;超载;
结束;
实施
{TMyClass}
构造函数TMyClass.Create;
开始
继承;
MyString:='';
MyStringList:=TStringList.Create;
MyStringList.Add('This');
MyStringList.Add('is');
MyStringList.Add('a');
MyStringList.Add('test');
结束;
构造函数TMyClass.Create(InitString:String);
开始
创造;
MyString:=InitString;
结束;
我希望能够根据需要使用两个TMyClass构造函数

constructor TMyClassList<T>.Create;
begin
  Add(T.Create);
//  Add(T.Create('test')); // <--- THIS FAILS ????
end;
构造函数TMyClassList.Create;
开始
添加(T.Create);

//添加(T.Create('test');// 不能对泛型类型指定常规构造函数约束。您所能做的就是指定它们有一个无参数构造函数,就像您所做的那样。像这样解决它:

TMyClassList<T: TMyClass> = class(TObjectList<T>)
//no need for constructor constraint
...
type
  TMyClassClass = class of TMyClass;
...
constructor TMyClassList<T>.Create;
begin
  Add(TMyClassClass(T).Create('test'));
end;
type
  TMyClassClass = class of TMyClass;

...

constructor TMyClassList<T>.Create;
begin
  Add(T.Create);
  Add(TMyClassClass(T).Create('test'));
end;

...

var
  Test : TMyClassList<TMyClass>;
begin
  Test := TMyClassList<TMyClass>.Create;
end;

另一个选项是使用无参数构造函数并使用单独的例程进行初始化。

您不能在泛型类型上指定常规构造函数约束。您所能做的就是指定它们有一个无参数构造函数,就像您所做的那样。像这样解决它:

TMyClassList<T: TMyClass> = class(TObjectList<T>)
//no need for constructor constraint
...
type
  TMyClassClass = class of TMyClass;
...
constructor TMyClassList<T>.Create;
begin
  Add(TMyClassClass(T).Create('test'));
end;
type
  TMyClassClass = class of TMyClass;

...

constructor TMyClassList<T>.Create;
begin
  Add(T.Create);
  Add(TMyClassClass(T).Create('test'));
end;

...

var
  Test : TMyClassList<TMyClass>;
begin
  Test := TMyClassList<TMyClass>.Create;
end;

另一个选项是使用无参数构造函数并使用单独的例程进行初始化。

我让它这样工作:

TMyClassList<T: TMyClass> = class(TObjectList<T>)
//no need for constructor constraint
...
type
  TMyClassClass = class of TMyClass;
...
constructor TMyClassList<T>.Create;
begin
  Add(TMyClassClass(T).Create('test'));
end;
type
  TMyClassClass = class of TMyClass;

...

constructor TMyClassList<T>.Create;
begin
  Add(T.Create);
  Add(TMyClassClass(T).Create('test'));
end;

...

var
  Test : TMyClassList<TMyClass>;
begin
  Test := TMyClassList<TMyClass>.Create;
end;
类型
TMyClassClass=TMyClassClass的类别;
...
构造函数TMyClassList.Create;
开始
添加(T.Create);
添加(TMyClassClass(T).Create('test');
结束;
...
变量
测试:TMyClassList;
开始
测试:=TMyClassList.Create;
结束;

我让它像这样工作:

TMyClassList<T: TMyClass> = class(TObjectList<T>)
//no need for constructor constraint
...
type
  TMyClassClass = class of TMyClass;
...
constructor TMyClassList<T>.Create;
begin
  Add(TMyClassClass(T).Create('test'));
end;
type
  TMyClassClass = class of TMyClass;

...

constructor TMyClassList<T>.Create;
begin
  Add(T.Create);
  Add(TMyClassClass(T).Create('test'));
end;

...

var
  Test : TMyClassList<TMyClass>;
begin
  Test := TMyClassList<TMyClass>.Create;
end;
类型
TMyClassClass=TMyClassClass的类别;
...
构造函数TMyClassList.Create;
开始
添加(T.Create);
添加(TMyClassClass(T).Create('test');
结束;
...
变量
测试:TMyClassList;
开始
测试:=TMyClassList.Create;
结束;

谢谢。我还在学习:-)。但是要正确理解它。即使我使用了类约束
TMyClassList
,我仍然必须将其强制转换为TMyClass。。这有点夸张。。如果你知道我的意思:-)?@David:如果我尝试“Add(TMyClass(T).Create('test')”,我会得到一个访问冲突(在delphixe2中)。这就是为什么我使用了TMyClassClass(T)。我们做的事情不同吗?是的:对不起-忘了我现在在XE。@Ville你说得很对。我错了。嗯。。。我想我有一种似曾相识的感觉。这个解决方案是在我看到的一篇旧帖子中提到的。我只是不记得在哪里,谢谢。我还在学习:-)。但是要正确理解它。即使我使用了类约束
TMyClassList
,我仍然必须将其强制转换为TMyClass。。这有点夸张。。如果你知道我的意思:-)?@David:如果我尝试“Add(TMyClass(T).Create('test')”,我会得到一个访问冲突(在delphixe2中)。这就是为什么我使用了TMyClassClass(T)。我们做的事情不同吗?是的:对不起-忘了我现在在XE。@Ville你说得很对。我错了。嗯。。。我想我有一种似曾相识的感觉。这个解决方案是在我看到的一篇旧帖子中提到的。我只是不记得在哪里。这是一个很好的解决方案。当我们把多形性放进这个里面会发生什么?假设我们从TMyClass和TMyClassList派生,比如
TOurClass=class(TMyClass)TOurClassList=class(TMyClassList)
在创建TOurClassList时,我们能在TOurClass的构造函数上实现真正的多态性吗??希望你能跟我来:-)@Bimmer\R你需要一个虚拟构造函数,就像我(现在更正)的答案一样。同样+1是为了在我没有做的地方得到正确的结果。@davidheffernanthx。但是删除构造函数约束将使我别无选择,只能为我创建的两个对象强制转换为TMyClassClass。。。正确的?事实上,我可以接受这一点——我只是在寻找一种正确的方法。在我的问题(在上面的评论中)中,我推测将多态性应用于此。事实上,我想我可能走错了路。。还是我?有什么建议吗?@Bimmer\R为什么需要多个构造函数?如果需要,请保留构造函数约束。我在回答中解释说,这里需要使用虚拟构造函数。@DavidHeffernan我正在重写一个相当大的库,allready实现了几个不同的构造函数。主要用于快速初始化,也用于决定如何构造实例。我们可以在构造函数中提供一个到我们的一个对象的TSQLConnection,通过这样做,构造函数知道还有很多东西需要初始化(datasnap/数据库等等)。这是一个很好的解决方案。当我们把多形性放进这个里面会发生什么?假设我们从TMyClass和TMyClassList派生,比如
TOurClass=class(TMyClass)TOurClassList=class(TMyClassList)
在创建TOurClassList时,我们能在TOurClass的构造函数上实现真正的多态性吗??希望你能跟我来:-)@Bimmer\R你需要一个虚拟构造函数,就像我(现在更正)的答案一样。同样+1是为了在我没有做的地方得到正确的结果。@davidheffernanthx。但是删除构造函数约束将使我别无选择,只能为我创建的两个对象强制转换为TMyClassClass。。。正确的?事实上,我可以接受这一点——我只是在寻找一种正确的方法。在我的问题(在上面的评论中)中,我推测将多态性应用于此。事实上,我想我可能走错了路。。还是我?有什么建议吗?