4

我有类TLuaClassTemplate<T: TControl, constructor> = class并尝试将它的方法class procedure RegisterClass(L: Plua_State; p: TPrintProc; container: TComponent; vm: TLuaVm); static;与存储在 TDictionary 中的 TControlClass 引用一起使用

  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 作为通用参数?

4

1 回答 1

4

您遇到的问题是泛型的实例化要求类型参数在编译时是已知的。你的代码cls在编译时是未知的,它只在运行时确定。这意味着这TLuaClassTemplate<cls>是泛型的无效实例化。

这里的底线是泛型为您的代码提供参数化,但必须在编译时提供参数。由于您直到运行时才知道参数,因此您无法使用泛型解决您的问题。

好吧,我说不能,但你可以使用 RTTI 来调用你的泛型方法。为此,您需要确保每个可能的实例化类型都包含在可执行文件的类型列表中。但是这样做真的会破坏泛型的目的!使用标准运行时参数比使用编译时通用参数要容易得多。

于 2013-03-24T16:57:40.343 回答