4

クラスがあり、TDictionaryに保存されているTControlClass参照でTLuaClassTemplate<T: TControl, constructor> = classそのメソッドを使用しようとしていますclass procedure RegisterClass(L: Plua_State; p: TPrintProc; container: TComponent; vm: TLuaVm); static;

  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 に答える