2012-07-14 11 views
8

क्या TryParse गतिशील रूप से कॉल करने का कोई तरीका है? कुछ प्रकार:गतिशील रूप से TryParse को कैसे कॉल करें?

public static bool TryParse<T>(string toConvert, out T result) 

बेशक कोई इसके लिए टाइपऑनटर का उपयोग कर सकता है। हालांकि, एक अवैध रूपांतरण के परिणामस्वरूप अपवाद होगा और मैं इससे छुटकारा पाना चाहता हूं।

+0

शायद तुम System.Reflection से कुछ इस्तेमाल कर सकते हैं। मैंने प्रतिबिंब के साथ जेनेरिकों के साथ निपटाया नहीं है, लेकिन यह टाइप प्रकार की जानकारी जैसा हो सकता है, देखें कि 'TryParse()' मौजूद है, यदि ऐसा है, तो 'Invoke() ', अन्यथा झूठी वापसी करें। – cyanic

+0

संबंधित: http://stackoverflow.com/a/6160588/445517 – CodesInChaos

+0

विशेष रूप से http://stackoverflow.com/a/2961921/103167 पर देखें, परिणाम को वापस कॉपी करना जोड़ें। –

उत्तर

9

आप प्रतिबिंब का उपयोग करके गतिशील रूप से TryParse विधि को कॉल कर सकते हैं। यदि रूपांतरण विफल रहता है तो इस तरह आपको समय लेने वाली अपवाद नहीं मिलेगी।

यह विधि इस one का थोड़ा अनुकूलित संस्करण है।

//Try Parse using Reflection 
public static bool TryConvertValue<T>(string stringValue, out T convertedValue) 
{ 
    var targetType = typeof(T); 
    if (targetType == typeof(string)) 
    { 
     convertedValue = (T)Convert.ChangeType(stringValue, typeof(T)); 
     return true; 
    } 
     var nullableType = targetType.IsGenericType && 
         targetType.GetGenericTypeDefinition() == typeof (Nullable<>); 
    if (nullableType) 
    { 
     if (string.IsNullOrEmpty(stringValue)) 
     { 
      convertedValue = default(T); 
      return true; 
     } 
      targetType = new NullableConverter(targetType).UnderlyingType; 
    } 

    Type[] argTypes = { typeof(string), targetType.MakeByRefType() }; 
    var tryParseMethodInfo = targetType.GetMethod("TryParse", argTypes); 
    if (tryParseMethodInfo == null) 
    { 
     convertedValue = default(T); 
     return false; 
    } 

    object[] args = { stringValue, null }; 
    var successfulParse = (bool)tryParseMethodInfo.Invoke(null, args); 
    if (!successfulParse) 
    { 
     convertedValue = default(T); 
     return false; 
    } 

    convertedValue = (T)args[1]; 
    return true; 
} 
+0

अच्छा। एक सुझाव: 'if (nullableType) 'ब्लॉक में, जब आप' null' के लिए' stringValue' चेक करते हैं, तो शायद आपको 'string.IsNullOrEmpty (stringValue)' कहना चाहिए। मुझे लगता है कि कारण यह है कि 'Nullable <>। ToString() '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' है। तो खाली स्ट्रिंग को उदाहरण के लिए वैध स्ट्रिंग प्रस्तुति माना जा सकता है '(Int?) Null'। इनपुट के लिए –

+1

धन्यवाद। हालांकि, अगर आप इस विधि को एक Nullable रूपांतरित करने के लिए कॉल करते हैं तो आउट मान शून्य होगा और वापसी मान गलत होगा। यह सही है क्योंकि "" पार्सिंग int के लिए वैध मान नहीं होना चाहिए? अगर मैं string.IsNullOrEmpty का उपयोग करता हूं तो रिटर्न वैल्यू सत्य होगा, जो सही इम्हो नहीं होगा। –

+1

यह बिल्कुल ठीक है। लेकिन इसका मतलब है कि एक 'शून्य''राउंड-ट्रिप "नहीं होगा। मान लीजिए कि आपके पास है: 'int? मैं = शून्य; स्ट्रिंग एस = i.ToString(); int? tmp; बूल कैनपर्स = TryConvertValue (एस, बाहर टीएमपी); '। फिर 'canParse' गलत होगा भले ही स्ट्रिंग '' int' '' ToString' कॉल से सीधे आती है। यह भी देखें [एमएसडीएन टूस्ट्रिंग] (http://msdn.microsoft.com/en-us/library/9hd15ket.aspx)। –

2

आप कुछ इस तरह लिख सकते हैं:

public delegate bool TryParser<T>(string input, out T result); 

public static bool TryParse<T> 
    (string toConvert, out T result, TryParser<T> tryParser = null) 
{ 
    if (toConvert == null) 
     throw new ArgumentNullException("toConvert"); 

    // This whole block is only if you really need 
    // it to work in a truly dynamic way. You can additionally consider 
    // memoizing the default try-parser on a per-type basis. 
    if (tryParser == null) 
    { 
     var method = typeof(T).GetMethod 
       ("TryParse", new[] { typeof(string), typeof(T).MakeByRefType() }); 

     if (method == null) 
      throw new InvalidOperationException("Type does not have a built in try-parser."); 

     tryParser = (TryParser<T>)Delegate.CreateDelegate 
      (typeof(TryParser<T>), method); 
    } 

    return tryParser(toConvert, out result); 
} 

और फिर इसे पसंद फोन:

int result; 
bool success = TryParse("123", out result); 

मैं वास्तव में इस की सिफारिश नहीं होगा जब तक आप कुछ परिदृश्य है कि यह आवश्यकता है।

+0

यह एक असाधारण खोज था। बहुत सराहना की। – BackDoorNoBaby

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