如何使用TypInfo RTTI方法将值设置为子属性项?

时间:2012-07-30 19:14:21

标签: delphi rtti delphi-2006

在我的问题中: How to use “Sender” parameter with “As” operator for more then one class at a time

我选择了Remy Lebeau的答案,因为它是大多数情况下最具活力的技术。它使用RTTI TypInfo类。

但是当我使用这个课时,又出现了另一个问题: 我们如何设置子属性值?

function TRemote.UpdateQuery(DataSet: TDataSet; SQL: String): Boolean;
var
  PropInfo: PPropInfo;
begin
{ atualiza o código SQL padrão de um dataSet de consulta tipo View }
  PropInfo := GetPropInfo(DataSet, 'SQL', []);
  if not Assigned(PropInfo) then
  begin
    Result := False;
    Exit;
  end;
  try
    DataSet.Close;
    SetPropValue(DataSet, PropInfo, SQL);
    DataSet.Open;
    Result := True;
  except
    Result := False;
  end;
end;

实施例: 我有一个TIBQuery,我想更新SQL属性的文本。 但是SQL属性是一个TStrings类,所以我必须使用SQL.Text。 在上面的代码中,它将引发错误“无效的属性类型”,因为我有一个TStrings,后来我尝试设置一个普通的字符串。

如何使用GetPropInfo访问SQL.Text? 是否有TIBQuery和TZQuery的共同祖先具有SQL属性,所以我可以更改为,而不是函数参数中的TDataSet?

1 个答案:

答案 0 :(得分:9)

在Delphi 2006中无法通过RTTI访问TStrings.Text属性。即使是这样,您也无需使用RTTI来访问它。既然您知道SQL属性是TStrings对象,您只需从属性中检索实际对象指针并将其类型转换为TStrings指针,然后就可以执行任何操作需要处理该对象,例如:

function TRemote.UpdateQuery(DataSet: TDataSet; SQL: String): Boolean; 
var 
  PropInfo: PPropInfo; 
  SQLObj: TStrings;
begin 
  Result := False; 
  try 
    PropInfo := GetPropInfo(DataSet, 'SQL', [tkClass]); 
    if not Assigned(PropInfo) then Exit; 
    SQLObj := TStrings(GetObjectProp(DataSet, PropInfo, TStrings));
    if not Assigned(SQLObj) then Exit; 
    DataSet.Close; 
    SQLObj.Text := SQL; 
    DataSet.Open; 
    Result := True; 
  except 
  end; 
end;