2009-12-22 18 views
12

तो मैं समझता हूं कि मुक्केबाजी और अनबॉक्सिंग क्या है। वास्तविक दुनिया कोड में यह कब आता है, या यह किस उदाहरण में एक मुद्दा है? मैं इस उदाहरण की तरह कुछ कर रही कल्पना कर सकते हैं नहीं:बॉक्सिंग और अनबॉक्सिंग: यह कब आता है?

int i = 123; 
object o = i;   // Boxing 
int j = (int)o;  // Unboxing 

... लेकिन यह है कि लगभग निश्चित रूप से अत्यंत oversimplified है और मैं पहले भी यह जाने बिना मुक्केबाजी/unboxing किया है हो सकता है।

+0

मैं आपसे सहमत हूं। इस विषय पर मैंने जो कुछ भी पढ़ा है, उससे मुझे बस बिंदु नहीं मिला है। कुछ याद आना चाहिए :) –

उत्तर

31

यह अधिक जेनिक्स से पहले की तुलना में अब एक समस्या से कम है। अब, उदाहरण के लिए, हम इसका उपयोग कर सकते हैं:

List<int> x = new List<int>(); 
x.Add(10); 
int y = x[0]; 

कोई मुक्केबाजी या अनबॉक्सिंग बिल्कुल आवश्यक नहीं है।

पहले, हम पड़ा है चाहते हैं:

ArrayList x = new ArrayList(); 
x.Add(10); // Boxing 
int y = (int) x[0]; // Unboxing 

था मेरी मुक्केबाजी और unboxing का सबसे आम अनुभव है, कम से कम।

जेनेरिक शामिल होने के बिना, मुझे लगता है कि मैं शायद कहूंगा कि परियोजनाओं में मुक्केबाजी का प्रतिबिंब सबसे आम कारण है जिस पर मैंने काम किया है। प्रतिबिंब एपीआई हमेशा एक विधि के लिए वापसी मूल्य जैसी चीज़ों के लिए "ऑब्जेक्ट" का उपयोग करते हैं - क्योंकि उनके पास इसका उपयोग करने का कोई और तरीका नहीं है।

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

+7

"मुझे लगता है कि मैं शायद कहूंगा कि परियोजनाओं में मुक्केबाजी का प्रतिबिंब सबसे आम कारण है जिस पर मैंने काम किया है" - यह निश्चित रूप से परियोजनाओं पर निर्भर करेगा। उदाहरण के लिए, यदि आप डब्ल्यूपीएफ या सिल्वरलाइट के साथ काम करते हैं, तो मुक्केबाजी * हर समय * होगी जब आप मूल्य कन्वर्टर्स (IValueConverter लेता है और रिटर्न ऑब्जेक्ट) के साथ काम करता है, निर्भरता गुण (निर्भरता ऑब्जेक्ट.गेटवेल्यू और सेटवैल्यू रिटर्न और ऑब्जेक्ट लेते हैं), आदि – itowlson

+0

+1 एक मान प्रकार पर लागू इंटरफेस के लिए - यह एक चुस्त है :) –

+0

@itowlson: वे महान उदाहरण हैं - दिमाग अगर मैं उन्हें अपने उत्तर में जोड़ूं? –

8

मुक्केबाजी (मेरे अनुभव में) आम तौर पर इन मामलों में होता है:

  • एक मान प्रकार एक विधि है कि प्रकार Object का एक तर्क स्वीकार करता है करने के लिए पारित कर दिया है।
  • एक गैर-जेनेरिक संग्रह में एक मान प्रकार जोड़ा जाता है (जैसे ArrayList)।

अन्य बार आप मुक्केबाजी देख सकते हैं और unboxing जब आप नेट ढांचे के प्रतिबिंब एपीआई के रूप में प्रतिबिंब का उपयोग Object का गहन उपयोग करता है।

+1

हमें यह ध्यान रखना होगा: int (Int32) अमूर्त वर्ग ValueType का उप-वर्ग है, जो ऑब्जेक्ट का उप-वर्ग है। –

+0

मैं नहीं कहूंगा कि यह एक "सबक्लास" है - यह बिल्कुल * कक्षा * नहीं है। यह 'वैल्यू टाइप' से प्राप्त होता है (या प्राप्त होता है)। सी # और सीएलआई स्पेक इस मोर्चे पर थोड़ा अलग शब्दावली का उपयोग करते हैं, जो मामलों की मदद नहीं करता है। –

1

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

निश्चित रूप से ऐसे मामले हैं जहां यह प्रासंगिक है। 2.0 ढांचे में जेनेरिकों को शामिल करने से अभ्यास के बाहर कई आम मुक्केबाजी मामले सामने आए।

+0

सी # 2, 2.0 ढांचे नहीं;) – disklosr

0

सी # 2.0 (विजुअल स्टूडियो 2005) के साथ जेनरिक का उपयोग करके दृढ़ता से टाइप की गई सूचियों और शब्दकोशों के आगमन के बाद से, मुझे लगता है कि मुक्केबाजी/अनबॉक्सिंग को ध्यान में रखते हुए महत्व को कम किया गया है। उस नालीबल प्रकारों में जोड़ें (int?, आदि) और नल कोलेसिंग ऑपरेटर (??) का उपयोग करके और यह वास्तव में बहुत अधिक चिंता का विषय नहीं होना चाहिए और संभवतः इसे किसी भी कोड में नहीं देखा जाएगा जो 1.1 फ्रेमवर्क या इससे पहले नहीं है।

+2

नहीं, जेनेरिक में अधिकांश लोगों की अपेक्षा की तुलना में बहुत अधिक मुक्केबाजी चल रही है। जब आप शून्य के खिलाफ unconstraint टी जांचते हैं तो सी # उत्सर्जित होगा। –

+0

मैं इसके साथ सहमत हूं - लेकिन जेनेरिक विधि/कक्षा को लागू करते समय डेवलपर का निर्णय लेने का निर्णय है। ढांचे के परिप्रेक्ष्य से, सामान्य संग्रह उपभोक्ता को मुक्केबाजी/अनबॉक्सिंग परिदृश्य से आगे निकलने की अनुमति देता है। जब मैं आपके द्वारा वर्णित परिदृश्य को कोड करता हूं, तो मेरी अनियंत्रित टी की तुलना डिफ़ॉल्ट (टी) के मुकाबले की जाएगी, न कि शून्य। अगर मैं * वास्तव में * शून्य के खिलाफ एक चेक की जरूरत है, टी बेहतर संदर्भ प्रकार के लिए बाध्य होना चाहिए। –

+0

"किसी भी कोड में जो 1.1 फ्रेमवर्क या पहले नहीं है" - एक साधारण स्ट्रिंग के बारे में क्या। फोर्मेट ("मेरा नंबर {0}", 123) है? – Alex

4

बॉक्सिंग/अनबॉक्सिंग तब होती है जब एक मान प्रकार (जैसे संरचना, int, long) किसी संदर्भ प्रकार को स्वीकार करता है - जैसे कि object

ऐसा तब होता है जब आप स्पष्ट रूप से ऐसी विधि बनाते हैं जो प्रकार ऑब्जेक्ट के पैरामीटर लेता है जो मूल्य प्रकारों को पारित किया जाएगा। यह तब भी आता है जब आप मूल्य प्रकार (आमतौर पर primitives) को स्टोर करने के लिए पुराने गैर-जेनेरिक संग्रह का उपयोग करते हैं।

आप String.Format() का उपयोग करते समय मुक्केबाजी के दौरान भी देखेंगे और इसके लिए प्राइमेटिव पास करेंगे। ऐसा इसलिए है क्योंकि String.Format() एक पैरा ऑब्जेक्ट स्वीकार करता है [] - जिसके परिणामस्वरूप कॉल में अतिरिक्त पैरामीटर का मुक्केबाजी होता है।

विधियों को आमंत्रित करने के प्रतिबिंब का उपयोग करने से मुक्केबाजी/अनबॉक्सिंग भी हो सकती है, क्योंकि प्रतिबिंब एपीआई के पास object वापस करने के अलावा कोई विकल्प नहीं है क्योंकि वास्तविक प्रकार संकलन समय पर ज्ञात नहीं है (और प्रतिबिंब एपीआई जेनेरिक नहीं हो सकते हैं)।

नए जेनेरिक संग्रह का परिणाम मुक्केबाजी/अनबॉक्सिंग में नहीं होता है, और इसलिए इस कारण के लिए पुराने संग्रहों के लिए बेहतर है (उदाहरण के लिए ऐरेलिस्ट, हैशटेबल, आदि)। उल्लेख नहीं है कि वे टाइपएफ़ हैं।

आप सामान्य रूप से वस्तुओं को स्वीकार करने वाले तरीकों को बदलकर मुक्केबाजी चिंताओं से बच सकते हैं।

public void string Decorate(object a) // passing a value type results in boxing 
{ 
    return a.ToString() + " Some other value"; 
} 

बनाम: उदाहरण के लिए:

public void string Decorate<T>(T a) 
{ 
    return a.ToString() + " some other value"; 
} 
1

यह सब समय था जब लोगों को नहीं पता क्या निहितार्थ हैं होता है, बस परवाह नहीं है या कभी कभी एक मदद नहीं कर सकता लेकिन कम के रूप में मुक्केबाजी को स्वीकार evel।

मजबूत टाइप किए गए डैटरोज़ बॉक्स/अनबॉक्स को हर समय जब आप मूल्य-प्रकार की संपत्ति तक पहुंचते हैं तो बहुत अधिक होगा। इसके अलावा, एक इंटरफ़ेस संदर्भ के रूप में एक मान प्रकार का उपयोग करके यह भी बॉक्स होगा। या एक मूल्य प्रकार के एक उदाहरण विधि से एक प्रतिनिधि प्राप्त हो रही है। (प्रतिनिधि के लक्ष्य प्रकार वस्तु का है)

3

यहाँ एक वास्तव में बुरा एक है :)

SqlCommand cmd = <a command that returns a scalar value stored as int>; 

// This code works very well. 
int result = (int)cmd.ExecuteScalar(); 

// This code will throw an exception. 
uint result = (uint)cmd.ExecuteScalar(); 

दूसरा अमल में विफल रहता है क्योंकि यह एक UInt32 जो संभव नहीं है में कोई Int32 Unbox की कोशिश करता है। तो आपको पहले और कास्ट करने से पहले अनबॉक्स करना होगा।

uint result = (uint)(int)cmd.ExecuteScalar(); 
+0

+1 उदाहरण प्रदान करने के लिए +1 – chikak

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