क्या कोई सामान्य पार्स () फ़ंक्शन है जो किसी स्ट्रिंग को पार्स का उपयोग करके किसी भी प्रकार में बदल देगा?


91

मैं एक स्ट्रिंग को जेनेरिक रिटर्न प्रकार पर intया dateउसके longआधार पर जेनेरिक प्रकार में बदलना चाहता हूं ।

मूल रूप से एक फ़ंक्शन जो Parse<T>(String)प्रकार का एक आइटम देता है T

उदाहरण के लिए यदि कोई इंट पास हो गया है तो फ़ंक्शन int.parseआंतरिक रूप से करना चाहिए ।

जवाबों:


132

System.Convert.ChangeType

अपने उदाहरण के अनुसार, आप कर सकते हैं:

int i = (int)Convert.ChangeType("123", typeof(int));
DateTime dt = (DateTime)Convert.ChangeType("2009/12/12", typeof(DateTime));

अपनी "जेनेरिक रिटर्न प्रकार" आवश्यकता को पूरा करने के लिए, आप अपनी खुद की एक्सटेंशन विधि लिख सकते हैं:

public static T ChangeType<T>(this object obj)
{
    return (T)Convert.ChangeType(obj, typeof(T));
}

यह आपको करने की अनुमति देगा:

int i = "123".ChangeType<int>();

शांत, लेकिन अजीब बात है इसका नाम ChangeType, इसलिए मैंने सोचा था कि यह फ़ंक्शन किसी तरह का कास्ट करता है और पार्स नहीं
करीम

7
MSDN का कहना है कि यह केवल एक आवरण है जो स्रोत ऑब्जेक्ट पर सही रूपांतरण विधि पाता है, जिसके लिए यह आवश्यक है कि वह IConvertin इंटरफ़ेस को लागू करता है।
ऐनी

यदि इसे लागू करने की आवश्यकता है तो IConvertableक्या आपको भी विवश नहीं होना चाहिए T, अर्थात T ChangeType<T>(this object obj) where T : IConvertable?
लियाम

2
@ लिम: नहीं, यह objहोना चाहिए IConvertible, लेकिन संकलन-समय पर इसे निर्दिष्ट करने का कोई तरीका नहीं है।
ऐनी

अगर मुझे TryChangeType जैसी किसी चीज़ की ज़रूरत है, जो असफल स्थिति में अशक्त या गलत है? केवल अपवाद को पकड़कर?
होपलेस

21

अच्छा लग रहा है कि मुझे इस धागे पर जवाब देने के लिए बहुत देर हो चुकी है। लेकिन यहाँ मेरा कार्यान्वयन है:

मूल रूप से, मैंने ऑब्जेक्ट क्लास के लिए एक्सटेंशन विधि बनाई है। यह सभी प्रकारों को संभालता है, अर्थात अशक्त, वर्ग और संरचना।

 public static T ConvertTo<T>(this object value)
           {
               T returnValue;

               if (value is T variable)
                   returnValue = variable;
               else
                   try
                   {
                       //Handling Nullable types i.e, int?, double?, bool? .. etc
                       if (Nullable.GetUnderlyingType(typeof(T)) != null)
                       {
                           TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
                           returnValue = (T) conv.ConvertFrom(value);
                       }
                       else
                       {
                           returnValue = (T) Convert.ChangeType(value, typeof(T));
                       }
                   }
                   catch (Exception)
                   {
                       returnValue = default(T);
                   }

               return returnValue;
           }

IMHO यह बेहतर जवाब है क्योंकि इसमें "अशक्त" -aspect भी है
Ole Albers

क्या कोई विशिष्ट कारण है कि आप TypeDescriptorअशक्त प्रकारों के लिए और Convert.ChangeTypeगैर-अशक्त लोगों के लिए उपयोग कर रहे हैं? इस पूरे tryब्लॉक TypeConverterको कोड की केवल 2 लाइनों तक कम किया जा सकता है और यह अशक्त और अशक्त दोनों के लिए काम करेगा।
IMujagic


8

प्रणय के उत्तर का क्लीनर संस्करण

public static T ConvertTo<T>(this object value)
{
    if (value is T variable) return variable;

    try
    {
        //Handling Nullable types i.e, int?, double?, bool? .. etc
        if (Nullable.GetUnderlyingType(typeof(T)) != null)
        {
            return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
        }

        return (T)Convert.ChangeType(value, typeof(T));
    }
    catch (Exception)
    {
        return default(T);
    }
}

0

एक प्रकार की वस्तुओं को दूसरे प्रकार में परिवर्तित करने के लिए .NET में कुछ जोड़े हैं।

लेकिन ये विधियाँ आपके विशिष्ट की तुलना में बहुत धीमी हैं T.Parse(string), मुक्केबाजी का कारण बनती हैं और हर बार जब आप एकल मान को परिवर्तित करना चाहते हैं तो बहुत सारे आवंटन शामिल करते हैं।

के लिए ValueString , मैं प्रकार प्रतिबिंब का उपयोग करने का एक उपयुक्त, स्थिर पार्स विधि मिल जाए, एक लैम्ब्डा अभिव्यक्ति यह बुला का निर्माण और भविष्य में उपयोग के लिए संकलित प्रतिनिधि (देखें कैश करने के लिए चुना है इस सवाल का जवाब एक उदाहरण के लिए)।

यह मेरे द्वारा ऊपर बताए गए तरीकों पर भी निर्भर करता है यदि प्रकार में एक उपयुक्त पार्सिंग विधि नहीं है ( रीडमी में प्रदर्शन अनुभाग देखें )।

var v = new ValueString("15"); // struct
var i = v.As<int>(); // Calls int.Parse.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.