I got code like this
name := 'Foo';
If name = 'Foo' then
result := TFoo.Create
else if name = 'Bar' then
result := TBar.Create
else if name = 'FooFoo' then
result := TFooFoo.Create;
Is there a way just to do
result := $name.create
or some way of creating class based of a variable value?
All the classes extended the same base class.
Starting with Delphi 2010, the enhanced RTTI allows you do this without having to creating your own Class Registry.
Using the RTTI
Unit you have several options available.
For Parameter Less Constructors one of the easiest is.
var
C : TRttiContext;
O : TObject;
begin
O := (C.FindType('UnitName.TClassName') as TRttiInstanceType).MetaClassType.Create;
...
end;
Here is an example of passing a parameter, using the TRttiMethod.Invoke()
var
C : TRttiContext;
T : TRttiInstanceType;
V : TValue;
begin
T := (C.FindType('StdCtrls.TButton') as TRttiInstanceType);
V := T.GetMethod('Create').Invoke(T.metaClassType,[self]);
(V.AsObject as TWinControl).Parent := self;
end;
I wrote several articles on the RTTI
unit as there is many options available.
Updated Based on David Request:
Comparing the usage of construction using the Class Type (Virtual Constructor) with the TRttiType.Invoke
I personally find each serves a different purpose. If I know all the types up front the I use the Class Type Method.
You can use the GetClass
function, but before you must register the classes using the RegisterClass
or RegisterClasses
methods.
GetClass(const AClassName: string): TPersistentClass;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With