You can always register your types in some registry (controlled by a string list or a dictionary) and create a factory function to return the corresponding object. Unfortunately, you need to know in advance what types you will need. Something similar to the Delphi RegisterClass and FindClass functions (in the class block). My thinking is to directly enter the generic type of the template into the list.
Possible use example:
RegisterCustomType('Integer',TSomeType<Integer>); RegisterCustomType('String',TSomeType<String>); if FindCustomType('Integer') <> nil then O := FindCustomType('Integer').Create;
EDIT: Here is a specific simple implementation using tDictionary from Generics.Collections to handle registry storage ... I will leave this extraction in useful methods as a simple exercise for the reader.
var o : TObject; begin TypeDict := TDictionary<String,TClass>.Create; TypeDict.Add('integer',TList<integer>); if TypeDict.ContainsKey('integer') then o := TypeDict.Items['integer'].Create; if Assigned(o) then ShowMessage(o.ClassName); end;
Another EDIT: I thought of this thought last night and discovered another technique that you can combine into this concept. Interfaces Here's a quick example of nothing, but it can be easily expanded:
TYPE ITest = interface ['{0DD03794-6713-47A0-BBE5-58F4719F494E}'] end; TIntfList<t> = class(TList<T>,ITest) public function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; end; procedure TForm1.Button7Click(Sender: TObject); var o : TObject; fTestIntf : ITest; begin TypeDict := TDictionary<String,TClass>.Create; TypeDict.Add('integer',TIntfList<integer>); if TypeDict.ContainsKey('integer') then o := TypeDict.Items['integer'].Create; if Assigned(o) and Supports(o,ITest,fTestIntf) then ShowMessage(o.ClassName); end;
Of course, you will have to implement the QueryInterface, _AddRef and _Release methods and extend the interface to do something more useful.
source share