我有一个类TLuaClassTemplate<T: TControl, constructor> = class
并尝试使用它的方法class procedure RegisterClass(L: Plua_State; p: TPrintProc; container: TComponent; vm: TLuaVm); static;
,其中TControlClass引用存储在TDictionary中
TClassNameToComponentDict = TDictionary<string, TControlClass>;
TClassNameToComponentPair = TPair<string, TControlClass>;
...
ClassNameToComponent := TClassNameToComponentDict.Create;
ClassNameToComponent.Add('TButton', TButton);
ClassNameToComponent.Add('TPanel', TPanel);
ClassNameToComponent.Add('TEdit', TEdit);
但我尝试使用它有问题
enum: TClassNameToComponentPair;
ctx: TRttiContext;
cls: TControlClass;
begin
for enum in vm.ClassNameToComponent do begin
//TLuaClassTemplate<enum.Value>.RegisterClass(vm.LS, PrintGlobal, container, vm);
cls := TControlClass((ctx.FindType(enum.Key) as TRttiInstanceType).MetaClassType);
TLuaClassTemplate<cls>.RegisterClass(vm.LS, PrintGlobal, container, vm);
end;
我已尝试过当前可见(通过搜索找到)和评论选项。但错误为Undeclared identifier: 'TLuaClassTemplate'
而TLuaClassTemplate<TButton>.RegisterClass(vm.LS, PrintGlobal, container, vm);
有效。
如何在这里使用TControlClass作为通用参数?
答案 0 :(得分:4)
您遇到的问题是泛型的实例化要求在编译时知道类型参数。在您的代码中,cls
在编译时是未知的,它仅在运行时确定。这意味着TLuaClassTemplate<cls>
是通用的无效实例化。
这里的底线是泛型为您提供代码参数化,但必须在编译时提供参数。由于您在运行时之前不知道参数,因此无法使用泛型来解决问题。
嗯,我说,不能,但您可以使用RTTI调用您的通用方法。为此,您需要确保每个可能的实例化类型都包含在可执行文件的类型列表中。但这样做真的会破坏仿制药的目的!使用标准运行时参数比编译时间泛型参数要容易得多。