Possible Duplicate:
Generics constructor with parameter constraint?
In my venture into Generics, I've now come to a dead end where I hope someone can point me to the hidden door :-)
Given this type
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 开发者_Go百科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;
I would like to be able to use both TMyClass constructors as needed.
constructor TMyClassList<T>.Create;
begin
Add(T.Create);
// Add(T.Create('test')); // <--- THIS FAILS ????
end;
But only the one without parameters is usable.
I forgot to mention - It does NOT fail ... It will not COMPILE !!
Why is that?
Regards Bimmer_R
I got it working like this:
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;
You can't specify general constructor constraints on generic types. All you can do is specify that they have a single parameterless constructor, as you have done. Work around it like this:
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;
You'll want to use a virtual constructor on TMyClass
to make this work as you intend.
TMyClass = class
constructor Create(InitString : String); virtual;
end;
The other option is to use a parameterless constructor and use a separate routine for initialization.
精彩评论