delphi – 如何正确使用TRttiMethod.Invoke中的字符串作为参数?
发布时间:2020-12-15 09:48:34 所属栏目:大数据 来源:网络整理
导读:我正在尝试使用RTTI使用Text-property来概括可视组件的内容验证,但是当我尝试将字符串值传递给TRttiMethod.Invoke时,我收到消息“Invalid Typecast”. (实际上是“UngültigeTypumwandlung”,但我猜,这是一个合适的翻译.) 假设所有传递的对象都是完美的,下面
我正在尝试使用RTTI使用Text-property来概括可视组件的内容验证,但是当我尝试将字符串值传递给TRttiMethod.Invoke时,我收到消息“Invalid Typecast”. (实际上是“UngültigeTypumwandlung”,但我猜,这是一个合适的翻译.)
假设所有传递的对象都是完美的,下面的代码将被删除所有安全措施,断言等. procedure ValidateTextFieldAndSetFocus(const Field: TObject; const Validator: TObject; const errorStates: array of TStringValidationResult; const sErrorMessage: string); var context : TRttiContext; objField : TRttiType; objValid : TRttiType; prop : TRttiProperty; execute : TRttiMethod; I : Integer; validResult : TStringValidationResult; value : TValue; begin context := TRttiContext.Create; objField := context.GetType(Field.ClassInfo); objValid := context.GetType(Validator.ClassInfo); prop := objField.GetProperty('Text'); value := prop.GetValue(Field); execute := objValid.GetMethod('Execute'); for I := 0 to High(errorStates) do if execute.Invoke(Validator,[value]).TryAsType<TStringValidationResult>(validResult) then if validResult = errorStates[I] then begin SetFocusIfCan(Field); raise Exception.Create(sErrorMessage); end; end; Validator的Execute只有一个string-Parameter.我已经看过将字符串直接传递到TValue数组的示例,但后来我得到了相同的类型转换错误. 编辑: 实际错误出现在execute.Invoke(Validator,[value])中. 例 TNoSemicolonNullValidator = class class function Execute(const aStr: string): TStringValidationResult; end; procedure TestValidation; var Validator : TNoSemicolonNullValidator; begin Validator := TNoSemicolonNullValidator.Create; try ValidateTextFieldAndSetFocus(Edit1,Validator,[svInvalid],'Edit1 is invalid!'); finally Validator.Free; end; end; 解决方法
您在此处调用类函数,但是您将TObject作为第一个参数传递(这是非静态方法的隐藏Self参数).在类方法上,Self参数不能是实例,而是它的类.所以正确的电话会是:
execute.Invoke(validator.ClassType,[value]); 这是一个证明: program Project1; {$APPTYPE CONSOLE} uses Rtti,SysUtils; type TValidator = class class function Execute(const s: string): Boolean; end; class function TValidator.Execute(const s: string): Boolean; begin Writeln(s); end; var ctx: TRttiContext; v: TValidator; begin v := TValidator.Create; try ctx.GetType(TValidator).GetMethod('Execute').Invoke(v,['test']); except on E: Exception do Writeln(E.ClassName,': ',E.Message); end; try ctx.GetType(TValidator).GetMethod('Execute').Invoke(v.ClassType,E.Message); end; Readln; end. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |