我有这样的代码
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;
有办法吗
result := $name.create
还是以某种方式创建基于变量值的类?
所有的类都扩展了相同的基类。
解决方法
从Delphi 2010开始,增强的RTTI允许您执行此操作,而无需创建自己的类注册表。
使用RTTI单元,您有几个选项可用。
对于参数较少的构造函数,最简单的一个是。
var C : TRttiContext; O : TObject; begin O := (C.FindType('UnitName.TClassName') as TRttiInstanceType).MetaClassType.Create; ... end;
以下是传递参数的示例,使用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;
我在RTTI单元上写了several articles,因为有很多选项可用。
根据大卫要求更新:
使用类型(虚拟构造函数)与TRttiType.Invoke进行比较
>在所有版本的Delphi中工作
>生成更快的代码
>需要编译时的祖先知识。
>需要一个类注册表通过字符串名称查找一个类(如RRUZ提到的)
TRttiType.Invoke()方法
>仅适用于Delphi 2010或更高版本。
>代码较慢
>实现引用名称冲突的类注册表
>编译时不需要祖先知识。
我个人觉得每个都有不同的目的。如果我知道前面的所有类型,我使用类类型方法。