2012-01-07 13 views
8

मुझे यह समझने में कठिनाई हो रही है। निम्न उदाहरण पर विचार करें:सी # - मुक्केबाजी/अनबॉक्सिंग/टाइपकास्टिंग इंक के साथ मुद्दे। मुझे समझ में नहीं आता

protected void Page_Load(object sender, EventArgs e) 
{ 
    // No surprise that this works 
    Int16 firstTest = Convert.ToInt16(0); 
    int firstTest2 = (int)firstTest; 

    // This also works 
    object secondTest = 0; 
    int secondTest2 = (int)secondTest; 

    // But this fails! 
    object thirdTest = Convert.ToInt16(0); 
    int thirdtest2 = (int)thirdTest; // It blows up on this line. 
} 

विशिष्ट त्रुटि है कि मैं रन टाइम पर मिल Specified cast is not valid. अगर मैं दृश्य स्टूडियो में (int)thirdTest QuickWatch है, मैं Cannot unbox 'thirdTest' as a 'int' के एक मूल्य मिलता है।

यहां बिल्ली क्या चल रहा है?

+1

Int16 वास्तव में एक छोटा सा है। तो मुझे लगता है कि आप 'Int16 firstTest = Convert.ToInt16 (0);' को प्रतिस्थापित कर सकते हैं; 'Int16 firstTest = 0s;' के साथ –

उत्तर

12

अनबॉक्सिंग documentation में बताए गए सटीक प्रकार की जांच करता है।

बॉक्स से निकालना एक मूल्य प्रकार करने के लिए या एक मान प्रकार है कि इंटरफ़ेस लागू करता है के लिए एक इंटरफेस प्रकार से टाइप वस्तु से एक स्पष्ट रूपांतरण है।

  • यकीन है कि यह दिया मान प्रकार की एक बॉक्स्ड मूल्य है बनाने के लिए वस्तु दृष्टान्त जाँच हो रही है: एक unboxing आपरेशन के होते हैं।

  • मान से मूल्य को मूल्य-प्रकार चर में कॉपी करना।

आप पहला कदम देख सकते हैं कि वस्तु उदाहरण लक्ष्य प्रकार से मेल खाता है की जाँच करने के लिए है।

भी दस्तावेज़ से बोली:

मूल्य प्रकार के unboxing के लिए रन टाइम पर सफल होने के लिए, आइटम अनबॉक्स्ड जा रहा है एक वस्तु है कि पहले का एक उदाहरण मुक्केबाजी द्वारा बनाया गया था के लिए एक संदर्भ होना चाहिए वह मान प्रकार। शून्य को अनबॉक्स करने का प्रयास करने से NullReferenceException का कारण बनता है। असंगत मान प्रकार के संदर्भ को अनबॉक्स करने का प्रयास करने से अमान्य कैस्टएक्सप्शन होता है।

तो इस त्रुटि Unbox करने के लिए प्रयास करने से पहले यह सुनिश्चित करें कि प्रकार से मेल खाता है ठीक करने के लिए:

object thirdTest = Convert.ToInt16(0); 
short thirdtest2 = (short)thirdTest; 
+2

या इसे सही प्रकार के साथ अनबॉक्स करें, फिर अपने वांछित प्रकार पर डालें। 'int thirdtest2 = (int) (लघु) तीसरातम;' –

9

क्या हो रहा है यह वास्तव में क्या कहते हैं।

पहले मामले में, आपके पास एक छोटा, अनबॉक्स किया गया है, जिसे आप स्पष्ट रूप से int में टाइपकास्टिंग कर रहे हैं। यह एक वैध रूपांतरण है कि संकलक जानता है कि कैसे करना है, इसलिए यह काम करता है।

दूसरे मामले में, आपके पास एक int, boxed है, जो एक int को वापस असाइन कर रहे हैं। यह एक पूर्णांक का एक सरल अनबॉक्सिंग है, जो मान्य भी है, इसलिए यह काम करता है।

तीसरे मामले में, आपके पास एक छोटा, बॉक्सिंग है, जो आप एक चर में अनबॉक्स करने की कोशिश कर रहे हैं जो कि छोटा नहीं है। यह एक वैध ऑपरेशन नहीं है: आप इसे एक चरण में नहीं कर सकते हैं।यह एक असामान्य समस्या नहीं है, या तो: यदि आप उपयोग कर रहे हैं, उदाहरण के लिए, एक SqlDataReader कि एक SMALLINT कॉलम होता है, तो आप ऐसा नहीं कर सकते:

int x = (int)rdr["SmallIntColumn"]; 

की या तो निम्नलिखित आपके तीसरा उदाहरण में काम करना चाहिए:

object thirdTest = Convert.ToInt16(0); 
    int thirdTest2 = Convert.ToInt32(thirdTest); 
    int thirdTest3 = (int)(short)thirdTest; 
4

Int16short लिखने का एक शानदार तरीका है; वहाँ कोई मुक्केबाजी/अनबॉक्सिंग नहीं है, बस 16-बिट और 32-बिट पूर्णांक के बीच सादा सीएलआर रूपांतरण।

दूसरे मामले के बक्से और उसी प्रकार के अनबॉक्स, जो अनुमति है: मूल्य प्रकार intobject में लपेटा जाता है, और फिर अनचाहे हो जाता है।

तीसरे मामले एक अलग प्रकार (int बजाय short) जिसकी अनुमति नहीं है करने के लिए Unbox की कोशिश करता है।

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