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

Ple*_*rds 3 delphi rtti delphi-2006

在我的问题: 如何使用"发件人"参数与"As"运算符一次超过一个类

我选择了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;
Run Code Online (Sandbox Code Playgroud)

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

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

Rem*_*eau 9

TStrings.Text在Delphi 2006中无法通过RTTI访问该属性.即使是这样,您也无需使用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; 
Run Code Online (Sandbox Code Playgroud)

  • +1; @EASI,我知道你已经具体问了这个,但你可以直接使用`GetObjectProp`.以前使用`GetPropInfo`没有任何优势(在其他`GetObjectProp`重载内部调用它). (2认同)
  • 在`GetObjectProp()`之前调用`GetPropInfo()`可以避免在找不到属性时引发异常.另一个重载版本的`GetObjectProp()`没有给你那个选项,它会引发异常.我认为在这种情况下由于`try/except`是正常的,但一般情况下,如果你可以避免异常,你可以避免与之相关的开销. (2认同)