如何设置一个值,使用TypInfo RTTI方法的子属性项目?(How to Set a Value

2019-09-20 11:16发布

在我的问题: 如何同时使用“发件人”参数与“为”运营商多个类

我选择了雷米勒博的答案,因为它是为像大多数情况下,最有活力的高科技。 它使用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属性是一个字符串列表类,所以我必须使用SQL.Text。 在上面的代码,它会产生一个错误“无效的属性类型,”因为我有一个字符串列表,后来我尝试设置一个正常的字符串。

如何使用GetPropInfo到达SQL.Text? 有TIBQuery和TZQuery具有SQL属性的一个共同的祖先,所以我可以改变,以代替在函数参数的数据集组件?

Answer 1:

TStrings.Text属性不是通过RTTI访问的德尔福2006年即使是这样,你不需要使用RTTI反正来访问它。 既然你知道SQL属性是一个TStrings对象,你可以简单地retreive从属性和类型强制转换为实际的对象指针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; 


文章来源: How to Set a Value to a Sub-Property Item using TypInfo RTTI Methods?