2017-08-22 18 views
16

पर काम नहीं करता है मेरे पास दो परीक्षण विधियां हैं। पहला एक ठीक काम करता है। दूसरा एक अपवाद नहीं फेंकता है, लेकिन यह चाहिए। दूसरे व्यक्ति ने अपवाद क्यों नहीं फेंक दिया?सी # इनलाइन चेक कथन

[TestMethod] 
[ExpectedException(typeof(OverflowException))] 
public void LongToInt_OverflowWithCheckedBlock() 
{ 
    checked 
    { 
     int maxValue = 2147483647; 
     long longValue = (maxValue + 1); 
     int intValue = (int)longValue; 
    } 
} 

[TestMethod] 
[ExpectedException(typeof(OverflowException))] 
public void LongToInt_OverflowWithCheckedStatement() 
{ 

    int maxValue = 2147483647; 
    long longValue = (maxValue + 1); 
    int intValue = checked((int)longValue);  // No Exception is thrown, why? 
} 
+9

आप एक * देर से रूपांतरण * बग है। 'longValue = maxValue + 1' 32 बिट पूर्णांक * अंक * में अंकगणित करता है और फिर 64 बिट में परिवर्तित होता है। इस बग का सबसे आम रूप 'डबल प्रतिशत = कुछ इंटेगर/100;' है, और सवाल तब है "मेरा प्रतिशत हमेशा शून्य क्यों है?" आपको उस अंक में कनवर्ट करना है जिसे आप अंकगणित करने के इरादे से पहले * * * अंकगणित करते हैं, नहीं * के बाद *। –

उत्तर

25

कारण पहले एक फेंकता है और दूसरा एक ऐसा इसलिए नहीं है क्योंकि आपकी तुलना थोड़ा सा है।

  • 1 विधि आप check सब कुछ
  • 2 विधि में आप केवल checklong से int के कलाकारों में।

आप उनकी तरह नीचे वे बराबर हैं तुलना और न फेंक देंगे:

private static void MethodA() 
{ 
    int maxValue = 2147483647; 
    long longValue = (maxValue + 1); 
    checked 
    { 
     int intValue = (int) longValue; 
    } 
} 

private static void MethodB() 
{ 
    int maxValue = 2147483647; 
    long longValue = (maxValue + 1); 
    int intValue = checked((int) longValue); 
} 

क्योंकि इस लाइन इस का कारण यह है: int intValue = checked((int) longValue); एक है कि फेंकने है, अपनी इस लाइन नहीं है :

long longValue = (maxValue + 1); 

अगर मैं वहाँ जाँच रख वे दोनों होगा फेंक:

long longValue = checked(maxValue + 1); 

क्यों इसे यहाँ फेंकता है:

यह फेंकता है क्योंकि (maxValue + 1) एक long को यह बताए कि के बाद एक int बुलाया maxValue (अपवाद यहाँ होता है) और को 1 जोड़ रहा है, यदि आप castint एक करने के लिए long जोड़ने 1 करने से पहले फेंक नहीं होगा:

long longValue = ((long) maxValue + 1); 
2

यही कारण है कि आप इसे long पर परिवर्तित कर रहे हैं। अनचेक (maxValue + 1) परिणाम -2147483648 में परिणाम जो आप long में संग्रहीत कर रहे हैं और इन-मोड़ कास्टिंग int पर कर रहे हैं। इस प्रकार अंतिम कलाकारों के बाद अपने intValue भंडार -2147483648

बजाय नीचे की तरह कोशिश करते हैं और यह परिणाम होगा में OverflowException

int intValue = checked(maxValue + 1); 

(या) भी

long longValue = checked((maxValue + 1)); 
8

MSDN document रूप ने कहा

जाँच कीवर्ड स्पष्ट अतिप्रवाह अभिन्न प्रकार अंकगणितीय आपरेशनों और रूपांतरण के लिए जाँच सक्षम किया जाता है।

पहला परीक्षण पद्धति पहले से ही अगर वहाँ घोषित ब्लॉक के भीतर एक उमड़ती मूल्य है जाँच कर रहा है।

enter image description here

दूसरे टेस्ट विधि केवल उमड़ती मूल्य केवल कोड की इस पंक्ति जाँच कर रहा है।

int intValue = checked((int)longValue); //Checked expression

enter image description here

के बाद से उमड़ती checked अभिव्यक्ति से पहले हो जाता है, CLR पहले से ही मूल्य बदल दिया। और उस का मूल्य -2147483648which is legal पूर्णांक रेंज के बाद से enter image description here

क्या अंतर है क्या है?

टेस्ट विधि 1: चेक किए गए ब्लॉक

टेस्ट विधि 2: की जाँच की अभिव्यक्ति

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