【问题标题】:How do I instantiate a class from its TRttiType?如何从其 TRttiType 实例化一个类?
【发布时间】:2013-02-07 02:24:27
【问题描述】:

我想创建一个表单,将其类名作为字符串which has been asked about before,但我不想调用GetClass,而是想使用Delphi 的新RTTI 功能。

有了这段代码,我有一个TRttiType,但我不知道如何实例化它。

var
  f:TFormBase;
  ctx:TRttiContext;
  lType:TRttiType;
begin
  ctx := TRttiContext.Create;
  for lType in ctx.GetTypes do
  begin
    if lType.Name = 'TFormFormulirPendaftaran' then
    begin
      //how to instantiate lType here?
      Break;
    end;
  end;
end;

我也试过lType.NewInstance,但没有成功。

【问题讨论】:

    标签: delphi delphi-xe2 rtti


    【解决方案1】:

    您必须将TRttiType 强制转换为TRttiInstanceType 类,然后使用GetMethod 函数调用构造函数。

    试试这个示例

    var
      ctx:TRttiContext;
      lType:TRttiType;
      t : TRttiInstanceType;
      f : TValue;
    begin
      ctx := TRttiContext.Create;
      lType:= ctx.FindType('UnitName.TFormFormulirPendaftaran');
      if lType<>nil then
      begin
        t:=lType.AsInstance;
        f:= t.GetMethod('Create').Invoke(t.MetaclassType,[nil]);
        t.GetMethod('Show').Invoke(f,[]);
      end;
    end;
    

    【讨论】:

    • 一旦你实例化了Form对象,你就不需要再使用RTTI来调用它的Show()方法了。正常调用即可:f.Show;
    • @RemyLebeau,在这个示例中 f 是一个 TValue,当然 OP 可以引入一个 TForm 辅助变量或者只是将 TValue 转换为一个 Tform,就像 TForm(f.AsObject).Show;
    • 抱歉,我没有注意到fTValue,我当时正在查看Niyoko 的代码。
    【解决方案2】:

    您应该使用TRttiContext.FindType() 方法而不是手动循环通过TRttiContext.GetTypes() 列表,例如:

    lType := ctx.FindType('ScopeName.UnitName.TFormFormulirPendaftaran');
    if lType <> nil then
    begin
      ...
    end;
    

    但无论哪种方式,一旦您找到了所需类类型的TRttiType,您就可以像这样实例化它:

    type
      TFormBaseClass = class of TFormBase;
    
    f := TFormBaseClass(GetTypeData(lType.Handle)^.ClassType).Create(TheDesiredOwnerHere);
    

    或者这个,如果TFormBase是从TForm派生的:

    f := TFormClass(GetTypeData(lType.Handle)^.ClassType).Create(TheDesiredOwnerHere);
    

    或者这个,如果TFormBase 派生自TCustomForm

    f := TCustomFormClass(GetTypeData(lType.Handle)^.ClassType).Create(TheDesiredOwnerHere);
    

    更新: 或者,像@RRUZ 显示的那样做。这更面向TRttiType,并且不依赖于使用旧的TypInfo 单元中的函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-08
      • 2021-10-13
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多