इसे समझने का सबसे अच्छा तरीका है कि निम्न-स्तरीय प्रोग्रामिंग भाषाओं को C # बनाया जाए।
सी जैसी निम्नतम-स्तरीय भाषाओं में, सभी चर एक स्थान पर जाते हैं: स्टैक। हर बार जब आप एक वैरिएबल घोषित करते हैं तो वह स्टैक पर चला जाता है। वे केवल आदिम मूल्य हो सकते हैं, जैसे कि एक बूल, एक बाइट, एक 32-बिट इंट, 32-बिट यूंट, आदि। स्टैक सरल और तेज दोनों है। जैसा कि चर जोड़े जाते हैं, वे बस एक दूसरे के ऊपर जाते हैं, इसलिए पहले आप घोषणा करते हैं, 0x00, अगला 0x01 पर, अगला 0x02 RAM में, आदि। इसके अलावा, चर अक्सर संकलन पर पूर्व-संबोधित होते हैं- समय, इसलिए उनका पता कार्यक्रम चलाने से पहले ही पता चल जाता है।
अगले स्तर में, सी ++ की तरह, हीप नामक एक दूसरी मेमोरी संरचना पेश की जाती है। आप अभी भी ज्यादातर स्टैक में रहते हैं, लेकिन पॉइंटर्स नामक विशेष किलों को स्टैक में जोड़ा जा सकता है, जो किसी ऑब्जेक्ट के पहले बाइट के लिए मेमोरी एड्रेस को स्टोर करता है, और वह ऑब्जेक्ट हीप में रहता है। ढेर एक तरह की गड़बड़ी है और बनाए रखने के लिए कुछ महंगा है, क्योंकि स्टैक चर के विपरीत वे रैखिक रूप से ढेर नहीं करते हैं और फिर एक कार्यक्रम निष्पादित करते हैं। वे किसी विशेष क्रम में आ और जा सकते हैं, और वे बढ़ सकते हैं और सिकुड़ सकते हैं।
संकेत से निपटना कठिन है। वे मेमोरी लीक, बफर ओवररन और फ्रस्ट्रेशन का कारण हैं। बचाव के लिए सी #।
एक उच्च स्तर पर, C #, आपको पॉइंटर्स के बारे में सोचने की ज़रूरत नहीं है - .Net फ्रेमवर्क (C ++ में लिखा गया) आपके लिए इन पर विचार करता है और उन्हें ऑब्जेक्ट्स के संदर्भ के रूप में आपके सामने प्रस्तुत करता है, और प्रदर्शन के लिए, आपको सरल मूल्यों को स्टोर करने देता है। बूल, बाइट्स और इन्ट्स जैसे वैल्यू टाइप। हुड के नीचे, ऑब्जेक्ट्स और सामान जो एक क्लास को तत्काल खर्च करते हैं, महंगे, मेमोरी-प्रबंधित हीप पर जाते हैं, जबकि वैल्यू टाइप उसी स्टैक में जाते हैं जो आपके पास निम्न-स्तरीय सी - सुपर-फास्ट में था।
कोडर के नजरिए से सरल (और स्टोरेज के लिए रणनीति) स्मृति के इन 2 मौलिक अवधारणाओं के बीच बातचीत को बनाए रखने के लिए, किसी भी समय मूल्य प्रकारों को बॉक्स किया जा सकता है। बॉक्सिंग स्टैक से कॉपी किए जाने वाले मूल्य का कारण बनता है, एक ऑब्जेक्ट में रखा जाता है, और ढेर पर रखा जाता है - संदर्भ दुनिया के साथ अधिक महंगा, लेकिन, द्रव अंतःक्रिया। जैसा कि अन्य उत्तर बताते हैं, यह तब होगा जब आप उदाहरण के लिए कहेंगे:
bool b = false; // Cheap, on Stack
object o = b; // Legal, easy to code, but complex - Boxing!
bool b2 = (bool)o; // Unboxing!
मुक्केबाजी के लाभ का एक मजबूत चित्रण शून्य के लिए एक जाँच है:
if (b == null) // Will not compile - bools can't be null
if (o == null) // Will compile and always return false
हमारे ऑब्जेक्ट ओ स्टैक में तकनीकी रूप से एक पता है जो हमारे बूल बी की एक प्रति को इंगित करता है, जिसे हीप में कॉपी किया गया है। हम n को n के लिए o चेक कर सकते हैं क्योंकि बूल बॉक्सेड है और वहां रखा गया है।
सामान्य तौर पर आपको बॉक्सिंग से बचना चाहिए जब तक कि आपको इसकी आवश्यकता न हो, उदाहरण के लिए एक इंट / बूल / जो एक तर्क के रूप में एक वस्तु के रूप में पारित हो। .Net में कुछ बुनियादी संरचनाएं हैं जो अभी भी ऑब्जेक्ट के रूप में पासिंग प्रकार की मांग करती हैं (और इसलिए बॉक्सिंग की आवश्यकता होती है), लेकिन अधिकांश भाग के लिए आपको कभी बॉक्स की आवश्यकता नहीं होनी चाहिए।
ऐतिहासिक सी # संरचनाओं की एक गैर-संपूर्ण सूची जिसमें बॉक्सिंग की आवश्यकता होती है, जिससे आपको बचना चाहिए:
ईवेंट सिस्टम यह बताता है कि इसके भोलेपन में रेस की स्थिति है, और यह एसिंक्स का समर्थन नहीं करता है। बॉक्सिंग समस्या में जोड़ें और इसे शायद टाला जाना चाहिए। (आप इसे एक एस्कॉन इवेंट सिस्टम के साथ उदाहरण के लिए बदल सकते हैं जो जेनरिक का उपयोग करता है।)
पुराने थ्रेडिंग और टाइमर मॉडल ने अपने मापदंडों पर एक बॉक्स को मजबूर किया, लेकिन इसे async / प्रतीक्षित द्वारा प्रतिस्थापित किया गया है जो कि दूर के क्लीनर और अधिक कुशल हैं।
.Net 1.1 संग्रह पूरी तरह से बॉक्सिंग पर निर्भर था, क्योंकि वे जेनरिक से पहले आए थे। ये अभी भी System.Collections में घूम रहे हैं। किसी भी नए कोड में आपको System.Collections.Generic से संग्रह का उपयोग करना चाहिए, जो बॉक्सिंग से बचने के अलावा आपको मजबूत प्रकार की सुरक्षा भी प्रदान करता है ।
आपको अपने मूल्य प्रकारों को वस्तुओं के रूप में घोषित करने या पारित करने से बचना चाहिए, जब तक कि आपको उपरोक्त ऐतिहासिक समस्याओं से निपटना न पड़े, जो बॉक्सिंग को मजबूर करती हैं, और आप बाद में इसे बॉक्सिंग के प्रदर्शन हिट से बचना चाहते हैं जब आप जानते हैं कि यह वैसे भी बॉक्सिंग होने जा रहा है।
नीचे मिकेल के सुझाव:
यह करो
using System.Collections.Generic;
var employeeCount = 5;
var list = new List<int>(10);
यह नहीं
using System.Collections;
Int32 employeeCount = 5;
var list = new ArrayList(10);
अपडेट करें
यह जवाब मूल रूप से Int32, बूल आदि के मुक्केबाजी का कारण बनता है, जब वास्तव में वे वैल्यू टाइप के लिए साधारण उपनाम हैं। यही है, .Net के पास बिना किसी कार्यात्मक अंतर के, बूल, Int32, स्ट्रिंग और C # उपनामों के प्रकार हैं जो उन्हें बूल, int, string में बदल देते हैं।