2008-09-14 13 views
15

यह कुछ लोगों के लिए प्राथमिक प्रतीत हो सकता है, लेकिन यह सवाल मुझ पर घबरा रहा है और जैसा कि मैंने कुछ कोड लिखा है, मुझे लगा कि मैं पूछूंगा।सी # कास्टिंग बनाम पार्स

इनमें से कौन सा सी # में बेहतर कोड है और क्यों?

((DateTime)g[0]["MyUntypedDateField"]).ToShortDateString() 

या

DateTime.Parse(g[0]["MyUntypedDateField"].ToString()).ToShortDateString() 
अंततः

, यह कास्ट करने के लिए या पार्स करने के लिए बेहतर है? सबको शुक्रीया!

उत्तर

12

यदि जी [0] ["MyUntypedDateField"] वास्तव में एक डेटटाइम ऑब्जेक्ट है, तो कास्ट बेहतर विकल्प है। यदि यह वास्तव में डेटटाइम नहीं है, तो आपके पास पार्स का उपयोग करने के अलावा कोई विकल्प नहीं है (यदि आपने कास्ट का उपयोग करने का प्रयास किया है तो आपको अमान्यकास्टएक्सप्शन मिलेगा)

+2

जब ऑब्जेक्ट डेटटाइम नहीं है, तो पार्स का उपयोग न करें, बल्कि ParseExact का उपयोग करें और अपेक्षित दिनांक और समय प्रारूप निर्दिष्ट करें, वर्तमान उपयोगकर्ता संस्कृति सेटिंग्स पर निर्भर होने से बचने के लिए। इस सवाल पर मेरा जवाब देखें। – qbeuek

0

जैसा कि @ ब्रायन आर बॉन्डी ने इंगित किया है कि यह जी के कार्यान्वयन पर निर्भर करता है [ 0] ["MyUntypedDateField"]। सुरक्षित अभ्यास डेटटाइम का उपयोग करना है। ट्राईपर्स और ऑपरेटर के रूप में।

+0

रक्षात्मक कोड लिखने से बचें। डेवलपर को पता होना चाहिए कि किस प्रकार का प्रारूप/प्रारूप अपेक्षित है और ** असफल ** (उदाहरण के लिए अपवाद फेंक दें) जब दिया गया मान एक अलग प्रारूप या प्रकार के साथ होता है। TryParse का उपयोग ** ** ** उपयोगकर्ता द्वारा प्रदान किए गए इनपुट पर किया जाना चाहिए। – qbeuek

+0

"चलो रक्षात्मक कोड लिखने से बचें" इसे दस लाख बार सुना। आम तौर पर यह खत्म होता है "अरे! उन्होंने आंतरिक कार्यान्वयन बदल दिया!" – aku

+0

@qbeuek .. क्या यह "इनपुट के साथ उदार और आउटपुट के साथ सख्त" नहीं होना चाहिए? – DefenestrationDay

0

पार्स इनपुट के लिए एक स्ट्रिंग की आवश्यकता है, कास्टिंग को ऑब्जेक्ट की आवश्यकता होती है, इसलिए दूसरे उदाहरण में आप ऊपर प्रदान करते हैं, तो आपको दो कोस्ट करने की आवश्यकता होती है: किसी ऑब्जेक्ट से स्ट्रिंग में, फिर स्ट्रिंग से डेटटाइम तक। पहला नहीं है।

हालांकि, अगर आप कास्ट करते समय अपवाद का खतरा होता है, तो हो सकता है कि आप दूसरा मार्ग जाना चाहें ताकि आप TryParse कर सकें और फेंकने के लिए एक महंगे अपवाद से बचें। अन्यथा, सबसे कुशल मार्ग पर जाएं और दो बार (ऑब्जेक्ट से स्ट्रिंग से डेटटाइम तक) एक बार (ऑब्जेक्ट से डेटटाइम तक) डालें।

3

कास्टिंग केवल अच्छा उत्तर है।

आपको याद रखना होगा कि ToString और Parse परिणाम हमेशा सटीक नहीं होते हैं - ऐसे मामले होते हैं, जब आप उन दो कार्यों के बीच सुरक्षित रूप से राउंडट्रिप नहीं कर सकते हैं।

ToString का प्रलेखन कहता है, यह वर्तमान थ्रेड संस्कृति सेटिंग्स का उपयोग करता है। पार्स का दस्तावेज कहता है, यह वर्तमान थ्रेड संस्कृति सेटिंग्स का भी उपयोग करता है (अब तक इतना अच्छा है - वे एक ही संस्कृति का उपयोग कर रहे हैं), लेकिन एक स्पष्ट टिप्पणी है, कि:

स्वरूपण वर्तमान के गुणों से प्रभावित है DateTimeFormatInfo ऑब्जेक्ट, जो डिफ़ॉल्ट रूप से नियंत्रण कक्ष में क्षेत्रीय और भाषा विकल्प आइटम से प्राप्त होता है। एक कारण पार्स विधि अनपेक्षित रूप से FormatException को फेंक सकती है, यदि वर्तमान दिनांक समय FormatInfo.DateSeparator और DateTimeFormatInfo.TimeSeparator गुण एक ही मान पर सेट हैं।

तो पर उन सेटिंग्स निर्भर करता है, ToString/पार्स कोड और अप्रत्याशित रूप से विफल हो जाएगा कर सकते हैं ...

1

आपका कोड पता चलता है कि चर या तो एक तारीख या एक स्ट्रिंग है कि एक तारीख की तरह लग रहा हो सकता है । तिथियां आप बुद्धिमानी को आसानी से वापस कर सकते हैं, लेकिन तारों को पार्स किया जाना चाहिए।पार्सिंग दो चेतावनी के साथ आता है;

  1. यदि आप निश्चित नहीं हैं कि इस स्ट्रिंग को पार्स किया जा सकता है, तो DateTime.TryParse() का उपयोग करें।

  2. हमेशा उस संस्कृति का संदर्भ शामिल करें जिसे आप पार्स करना चाहते हैं। ToShortDateString() विभिन्न स्थानों पर विभिन्न आउटपुट देता है। आप लगभग उसी संस्कृति का उपयोग करके पार्स करना चाहते हैं। मैं सुझाव देता हूं कि यह कार्य दोनों स्थितियों से निपट रहा है;

    private DateTime ParseDateTime(object data) 
    { 
        if (data is DateTime) 
        { 
         // already a date-time. 
         return (DateTime)data; 
        } 
        else if (data is string) 
        { 
         // it's a local-format string. 
         string dateString = (string)data; 
         DateTime parseResult; 
         if (DateTime.TryParse(dateString, CultureInfo.CurrentCulture, 
               DateTimeStyles.AssumeLocal, out parseResult)) 
         { 
          return parseResult; 
         } 
         else 
         { 
          throw new ArgumentOutOfRangeException("data", 
               "could not parse this datetime:" + data); 
         } 
        } 
        else 
        { 
         // it's neither a DateTime or a string; that's a problem. 
         throw new ArgumentOutOfRangeException("data", 
               "could not understand data of this type"); 
        } 
    } 
    

तो इस तरह कहते हैं;

ParseDateTime(g[0]["MyUntypedDateField").ToShortDateString(); 

ध्यान दें कि खराब डेटा अपवाद फेंकता है, तो आप इसे पकड़ना चाहेंगे।

इसके अलावा; 'as' ऑपरेटर डेटटाइम डेटा प्रकार के साथ काम नहीं करता है, क्योंकि यह केवल संदर्भ प्रकारों के साथ काम करता है, और डेटटाइम एक मान प्रकार है।

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