delphi 通过RTTI访问TList类

unftdfkk  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(224)

我想实现一个列表类型属性的Add方法。但是我得到了“Invalid class typecast”的错误。有人对此有什么想法吗?
Company.pas

TEmployes = class
  private
    FLastName: String;
    FFirstName: String;
  public
    property FirstName: String
      read FFirstName write FFirstName;
    property LastName: String
      read FLastName write FLastName;
  end;

  TContext = class
  private
    FEmployess: TList<TEmployes>;
  public
    constructor Create;
    destructor Destroy; override;
    property Employess: TList<TEmployes>
      read FEmployess write FEmployess;
  end;

Project1.pas

var Context: TContext := TContext.Create;

  var rContext: TRttiContext := TRttiContext.Create;
  var rIns : TRttiInstanceType :=
    rContext.GetType(Context.ClassInfo) as TRttiInstanceType;

  for var prop in rIns.GetProperties do
  begin
    var method: TRttiMethod := prop.PropertyType.GetMethod('Add');
    var emp: TEmployes := TEmployes.Create;
    emp.FirstName := 'Username';
    method.Invoke(prop.ClassInfo, [emp]);
  end;

  Context.Free;
rqqzpn5f

rqqzpn5f1#

您没有指出哪一行代码引发了错误。
但是,使用RTTI访问和调用TList<T>.Add()方法的方式肯定是错误的,基本上调用RTTI是为了执行以下等效操作:

for (<Every Property in TContext>) do
begin
  var emp: TEmployes := TEmployes.Create;
  emp.FirstName := 'Username';
  TList<TEmployes>(TRttiProperty.ClassInfo).Add(emp);
end;

您真正需要调用的是以下等效代码:

var Context: TContext := TContext.Create;

for (However Many Employees you need) do
begin
  var emp: TEmployes := TEmployes.Create;
  emp.FirstName := 'Username';
  Context.Employess.Add(emp);
end;

Context.Free;

这意味着您需要实际读取Context对象的Employess属性以获取其TList对象,然后您可以在该TList对象上调用Add(),例如:

var Context: TContext := TContext.Create;

var rContext: TRttiContext := TRttiContext.Create;
var rIns : TRttiType := rContext.GetType(Context.ClassInfo);

var prop : TRttiProperty := rIns.GetProperty('Employess');
var method: TRttiMethod := prop.PropertyType.GetMethod('Add');
var list : TObject := prop.GetValue(Context).AsObject;

for (However Many Employees you need) do
begin
  var emp: TEmployes := TEmployes.Create;
  emp.FirstName := 'Username';
  method.Invoke(list, [emp]);
end;

Context.Free;

相关问题