2015-09-04 8 views
5

मैं आरटीटीआई का उपयोग कर टेक्स्ट-प्रॉपर्टी के साथ दृश्य घटकों की सामग्री सत्यापन को सामान्यीकृत करने की कोशिश कर रहा हूं, लेकिन जब मैं TRttiMethod.Invoke में स्ट्रिंग मान पास करने का प्रयास करता हूं, तो मुझे संदेश "अमान्य टाइपकास्ट" मिलता है। (असल में "Ungültige Typumwandlung" लेकिन मुझे लगता है कि यह एक उपयुक्त अनुवाद था।)मैं TRttiMethod.Invoke में स्ट्रिंग का सही तरीके से उपयोग कैसे करूं?

नीचे दिया गया कोड सभी सुरक्षा उपायों, दावों और इतने पर छीन लिया गया है, मानते हैं कि सभी पास की गई वस्तुएं बिल्कुल सही हैं।

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; 

वैलिडेटर निष्पादन में केवल एक स्ट्रिंग-पैरामीटर है। मैंने उदाहरण देखे हैं जहां तारों को सीधे टीवीएयू की सरणी में पारित किया गया था, लेकिन फिर मुझे एक ही टाइपकास्ट त्रुटि मिलती है।

संपादित करें: 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; 
+0

प्रदान करें एक [mcve] तो हम भागों कि –

+0

याद कर रहे हैं लगता है की जरूरत नहीं है कि जैसा कि यह खड़ा है, इस सवाल को विषय से दूर होने के रूप में बंद किया जाना चाहिए। क्योंकि आपने प्रजनन प्रदान नहीं किया है। एक बार जब आप इसका समाधान कर लें (ऊपर टिप्पणी में लिंक देखें), तो हम जवाब देने में सक्षम होंगे। –

+0

असल में कोड गलती को खोजने के लिए पर्याप्त जानकारी प्रदान करता है। –

उत्तर

13

आप एक वर्ग समारोह यहां बुला रहे हैं, लेकिन आप पहले पैरामीटर (जो गैर स्थिर तरीकों में से छिपा स्व तर्क है) के रूप में एक TObject गुजर रहे हैं। एक वर्ग विधि पर स्वयं पैरामीटर एक उदाहरण नहीं होना चाहिए बल्कि इसकी कक्षा होना चाहिए। तो सही कॉल होगा:

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, ['test']); 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 
संबंधित मुद्दे

 संबंधित मुद्दे