Delphi 10.4:从属性动态获取TXS值(将TValue转换为TXS类)
解决Delphi Rtti读取TXSString类型属性值的问题
我明白你的困扰——用Rtti读取SOAP接口生成的TXSString类型属性时,直接调用AValue.ToString()只能拿到对象的内存地址,根本取不到实际的字符串内容。这是因为TXSString是类类型,TValue里存的是它的实例引用,默认的ToString只会输出对象标识,而非内部存储的字符串值。
解决思路
我们需要先判断当前TValue是否指向TXSString(或其派生类)的实例,再将其转换为TXSString对象,最后通过它的Value属性获取实际字符串。同时要注意处理属性值为nil的情况,避免空指针错误。
修改后的完整代码
uses System.TypInfo, system.Rtti, xmldom, XMLIntf, xsbuilder; // 确保引入TXSString所在单元 procedure TForm.GetObjectProperties(AObject: TObject; AList: TStrings); var ctx: TRttiContext; rType: TRttiType; rProp: TRttiProperty; AValue: TValue; sVal: string; TXSStringInst: TXSString; const SKIP_PROP_TYPES = [tkUnknown, tkInterface]; begin if not Assigned(AObject) or not Assigned(AList) then Exit; // 修正逻辑:任一参数为空直接退出 ctx := TRttiContext.Create; try // 用try-finally确保Rtti上下文资源释放 rType := ctx.GetType(AObject.ClassInfo); for rProp in rType.GetProperties do begin if (rProp.IsReadable) and not(rProp.PropertyType.TypeKind in SKIP_PROP_TYPES) then begin AValue := rProp.GetValue(AObject); if AValue.IsEmpty then begin sVal := 'nil'; end else begin // 处理普通字符串类型 if AValue.Kind in [tkUString, tkString, tkWString, tkChar, tkWChar] then sVal := QuotedStr(AValue.ToString) // 专门处理TXSString类型 else if AValue.IsObject and (AValue.AsObject is TXSString) then begin TXSStringInst := TXSString(AValue.AsObject); if Assigned(TXSStringInst) then sVal := QuotedStr(TXSStringInst.Value) else sVal := 'nil'; end // 其他类型 fallback 到默认ToString else sVal := AValue.ToString; end; AList.Add(rProp.Name + '=' + sVal); end; end; finally ctx.Free; end; end;
关键细节说明
- 类型判断逻辑:先用
AValue.IsObject确认是对象实例,再用is TXSString匹配具体类型,这样能兼容TXSString的派生类(如果SOAP生成了特殊子类的话)。 - 安全访问:转换后先检查
TXSStringInst是否为nil,避免空指针异常。 - 获取实际值:TXSString的
Value属性就是存储实际字符串的核心字段,直接读取它就能得到你需要的内容。 - 资源管理:给TRttiContext加上
try-finally块,确保资源正确释放,避免内存泄漏。
修改后你的代码就能正确读取TXSString类型属性的实际字符串值,不会再输出内存地址了。
内容的提问来源于stack exchange,提问作者fisi-pjm
相关产品推荐
相关产品推荐

