C # में, स्ट्रिंग एक संदर्भ प्रकार क्यों है जो एक मूल्य प्रकार की तरह व्यवहार करता है?


371

एक स्ट्रिंग एक संदर्भ प्रकार है, भले ही इसमें अपरिवर्तनीय होने और पाठ को तुलना करने के लिए == अतिभारित होने के बजाय एक मान प्रकार की अधिकांश विशेषताएँ हैं, यह सुनिश्चित करने के बजाय कि वे एक ही वस्तु को संदर्भित करते हैं।

स्ट्रिंग सिर्फ एक मूल्य प्रकार क्यों नहीं है?


चूंकि अपरिवर्तनीय प्रकारों के लिए भेद अधिकतर कार्यान्वयन-विस्तार ( isपरीक्षणों को छोड़कर ) है, इसका उत्तर संभवतः "ऐतिहासिक कारणों से" है। नकल का प्रदर्शन इसका कारण नहीं हो सकता क्योंकि शारीरिक रूप से अपरिवर्तनीय वस्तुओं की नकल करने की कोई आवश्यकता नहीं है। अब बिना ब्रेकिंग कोड को बदलना असंभव है जो वास्तव में isचेक (या समान बाधाओं) का उपयोग करता है।
इलाजरत

BTW यह C ++ के लिए एक ही उत्तर है (हालांकि भाषा में मूल्य और संदर्भ प्रकारों के बीच अंतर स्पष्ट नहीं है), std::stringएक संग्रह की तरह व्यवहार करने का निर्णय एक पुरानी गलती है जिसे अब तय नहीं किया जा सकता है।
इलाजरत

जवाबों:


333

स्ट्रिंग्स प्रकार के मूल्य नहीं हैं क्योंकि वे विशाल हो सकते हैं, और ढेर पर संग्रहीत करने की आवश्यकता होती है। स्टैक पर संग्रहीत मान प्रकार (अभी तक CLR के सभी कार्यान्वयन में) हैं। स्टैक आवंटन स्ट्रिंग्स सभी प्रकार की चीजों को तोड़ देगा: स्टैक 32 एमबी के लिए केवल 1 एमबी और 64-बिट के लिए 4 एमबी है, आपको प्रत्येक स्ट्रिंग को बॉक्स करना होगा, कॉपी पेनल्टी लगाना, आप इंटर्न स्ट्रिंग्स और मेमोरी का उपयोग नहीं कर सकते हैं गुब्बारा, आदि ...

(संपादित करें: मूल्य प्रकार के भंडारण के बारे में जोड़ा गया स्पष्टीकरण कार्यान्वयन कार्यान्वयन विवरण है, जो इस स्थिति की ओर ले जाता है जहां हमारे पास एक प्रकार का मूल्य है जो सिस्टम से विरासत में नहीं मिला।


75
मैं यहां नाइटपैकिंग कर रहा हूं, लेकिन केवल इसलिए कि यह मुझे प्रश्न के लिए प्रासंगिक ब्लॉग पोस्ट से लिंक करने का अवसर देता है: मूल्य प्रकार आवश्यक रूप से स्टैक पर संग्रहीत नहीं होते हैं। यह ms.net में सबसे अधिक बार सच है, लेकिन सीएलआई विनिर्देश द्वारा निर्दिष्ट नहीं है। मूल्य और संदर्भ प्रकारों के बीच मुख्य अंतर यह है कि संदर्भ प्रकार प्रतिलिपि-दर-मूल्य शब्दार्थ का अनुसरण करते हैं। देखें blogs.msdn.com/ericlippert/archive/2009/04/27/... और blogs.msdn.com/ericlippert/archive/2009/05/04/...
बेन Schwehn

8
@ क्वर्टी: Stringपरिवर्तनशील आकार नहीं है। जब आप इसे जोड़ते हैं, तो आप वास्तव में एक अन्य Stringऑब्जेक्ट बना रहे हैं , इसके लिए नई मेमोरी आवंटित करते हैं।
codekaizen

5
कहा कि, एक स्ट्रिंग, सिद्धांत रूप में, एक मूल्य प्रकार (एक संरचना) हो सकता है, लेकिन "मूल्य" स्ट्रिंग के संदर्भ से ज्यादा कुछ नहीं होता। .NET डिजाइनरों ने स्वाभाविक रूप से बिचौलिया को काटने का फैसला किया (.NET हैंडलिंग 1.0 में अक्षम था, और यह जावा का पालन करने के लिए स्वाभाविक था, जिसमें तार पहले से ही एक संदर्भ के रूप में परिभाषित किए गए थे, बजाय आदिम, प्रकार प्लस, अगर स्ट्रिंग थे। एक मान प्रकार फिर इसे ऑब्जेक्ट में परिवर्तित करने के लिए इसे बॉक्सिंग, एक अनावश्यक अक्षमता) की आवश्यकता होगी।
क्वर्टी

7
@codekaizen Qwertie सही है लेकिन मुझे लगता है कि शब्दांकन भ्रामक था। एक स्ट्रिंग एक और स्ट्रिंग की तुलना में एक अलग आकार हो सकती है और इस प्रकार, एक सच्चे मूल्य प्रकार के विपरीत, संकलक पहले से नहीं जान सकता था कि स्ट्रिंग मान को संग्रहीत करने के लिए कितना स्थान आवंटित करना है। उदाहरण के लिए, एक Int32हमेशा 4 बाइट्स होता है, इस प्रकार संकलक 4 बाइट्स आवंटित करता है जब भी आप एक स्ट्रिंग चर को परिभाषित करते हैं। कंपाइलर को कितनी मेमोरी आवंटित करनी चाहिए जब वह एक intवैरिएबल से टकराता है (यदि यह एक वैल्यू टाइप था)? यह समझें कि मान अभी तक असाइन नहीं किया गया है।
केविन ब्रॉक

2
क्षमा करें, मेरी टिप्पणी में एक टाइपो जिसे मैं अब ठीक नहीं कर सकता; यह होना चाहिए .... उदाहरण के लिए, एक Int32हमेशा 4 बाइट्स होता है, इस प्रकार कंपाइलर 4 बाइट्स आवंटित करता है जब भी आप किसी intचर को परिभाषित करते हैं। कंपाइलर को कितनी मेमोरी का आवंटन करना चाहिए, जब वह एक stringवैरिएबल से टकराता है (यदि यह एक वैल्यू टाइप था)? यह समझें कि मान अभी तक असाइन नहीं किया गया है।
केविन ब्रॉक

57

यह मान का प्रकार नहीं है क्योंकि प्रदर्शन (स्थान और समय!) भयानक होगा यदि यह एक मूल्य प्रकार है और इसके मूल्य को हर बार कॉपी किया जाना था और इसे विधियों से वापस लौटा दिया गया था, आदि।

दुनिया को बचाए रखने के लिए इसका अर्थ शब्दार्थ है। क्या आप कल्पना कर सकते हैं कि अगर कोड करना कितना मुश्किल होगा

string s = "hello";
string t = "hello";
bool b = (s == t);

सेट bहोने के लिए false? कल्पना करें कि किसी भी एप्लिकेशन के बारे में कोडिंग कितना मुश्किल होगा।


44
जावा को पिथी होने के लिए नहीं जाना जाता है।
जेसन

3
@ मैट: बिल्कुल। जब मैंने C # पर स्विच किया तो यह एक तरह से भ्रमित करने वाला था, क्योंकि मैंने हमेशा तार का उपयोग करने के लिए। (A) अभी भी कभी-कभी। मैंने कभी नहीं समझा कि उन्होंने संदर्भों की तुलना करने के लिए "==" क्यों नहीं छोड़ा, हालांकि अगर आपको लगता है, तो 90% समय आप शायद सामग्री की तुलना करना चाहेंगे न कि तार के संदर्भों की।
जूरी

7
@ ज़री: वास्तव में मुझे लगता है कि संदर्भों की जाँच करना कभी भी वांछनीय नहीं है, क्योंकि कभी-कभी new String("foo");और कोई new String("foo")भी उसी संदर्भ में मूल्यांकन कर सकता है कि किस तरह का ऐसा नहीं है जिसे आप एक newऑपरेटर से करने की उम्मीद करेंगे । (या आप मुझे एक मामला बता सकते हैं जहाँ मैं संदर्भों की तुलना करना चाहूंगा?)
माइकल

1
@ मिचेल ठीक है, आपको अशक्त की तुलना करने के लिए सभी तुलनाओं में एक संदर्भ तुलना शामिल करनी होगी। तार के साथ संदर्भों की तुलना करने के लिए एक और अच्छी जगह है, जब समानता-तुलना के बजाय तुलना की जाती है। दो समतुल्य तार, जब तुलना वापस आनी चाहिए 0. इस मामले की जाँच हालांकि पूरी तरह से पूरी तरह से चलने में जितनी देर लगती है, उतनी उपयोगी शॉर्ट-कट नहीं है। के लिए जाँच करना ReferenceEquals(x, y)एक तेज़ परीक्षा है और आप तुरंत 0 वापस कर सकते हैं, और जब आपके नल-परीक्षण के साथ मिलाया जाता है, तो यह किसी भी अधिक काम को नहीं जोड़ता है।
जॉन हन्ना

1
... स्ट्रिंग्स होना एक क्लास के टाइप होने के बजाय उस स्टाइल का एक वैल्यू टाइप होगा, जिसका मतलब होता है कि stringएक शून्य स्ट्रिंग के रूप में एक खाली स्ट्रिंग (जैसा कि यह प्री-.net सिस्टम में था) के रूप में व्यवहार कर सकता है। वास्तव में, मेरी अपनी प्राथमिकता एक मूल्य प्रकार की होगी Stringजिसमें एक संदर्भ-प्रकार होता है NullableString, जिसमें पूर्व में एक डिफ़ॉल्ट मान होता है String.Emptyऔर बाद वाला एक डिफ़ॉल्ट होता है null, और विशेष बॉक्सिंग / अनबॉक्सिंग नियमों के साथ (जैसे कि एक डिफ़ॉल्ट बॉक्सिंग) मूल्यवान ) के NullableStringलिए एक संदर्भ मिलेगा String.Empty
सुपरकैट

26

संदर्भ प्रकारों और मूल्य प्रकारों के बीच का अंतर मूल रूप से भाषा के डिजाइन में एक प्रदर्शन व्यापार है। निर्माण और विनाश और कचरा संग्रह पर संदर्भ प्रकार कुछ ओवरहेड हैं, क्योंकि वे ढेर पर बनाए गए हैं। दूसरी ओर वैल्यू टाइप्स मेथड कॉल्स पर ओवरहेड होते हैं (यदि डेटा का आकार एक पॉइंटर से बड़ा है), क्योंकि पूरे ऑब्जेक्ट को केवल पॉइंटर के बजाय कॉपी किया जाता है। क्योंकि तार एक पॉइंटर के आकार से बहुत बड़े (और आमतौर पर) हो सकते हैं, उन्हें संदर्भ प्रकारों के रूप में डिज़ाइन किया गया है। इसके अलावा, जैसा कि Servy ने बताया, एक मूल्य प्रकार का आकार संकलन समय पर ज्ञात होना चाहिए, जो हमेशा स्ट्रिंग के लिए नहीं होता है।

उत्परिवर्तन का प्रश्न एक अलग मुद्दा है। संदर्भ प्रकार और मूल्य प्रकार दोनों परस्पर या अपरिवर्तनीय हो सकते हैं। मूल्य प्रकार आमतौर पर अपरिवर्तनीय होते हैं, क्योंकि उत्परिवर्ती मूल्य प्रकारों के लिए शब्दार्थ भ्रमित हो सकते हैं।

संदर्भ प्रकार आम तौर पर परिवर्तनशील होते हैं, लेकिन इसे समझ में आने पर अपरिवर्तनीय के रूप में डिजाइन किया जा सकता है। स्ट्रिंग्स को अपरिवर्तनीय के रूप में परिभाषित किया जाता है क्योंकि यह कुछ अनुकूलन को संभव बनाता है। उदाहरण के लिए, यदि एक ही स्ट्रिंग शाब्दिक एक ही प्रोग्राम (जो कि काफी सामान्य है) में कई बार होता है, तो कंपाइलर उसी ऑब्जेक्ट का पुन: उपयोग कर सकता है।

तो पाठ द्वारा तार की तुलना करने के लिए "==" क्यों अतिभारित है? क्योंकि यह सबसे उपयोगी शब्दार्थ है। यदि दो तार पाठ के बराबर हैं, तो वे अनुकूलन के कारण समान वस्तु संदर्भ हो सकते हैं या नहीं भी हो सकते हैं। इसलिए तुलनात्मक संदर्भ बहुत बेकार हैं, जबकि पाठ की तुलना लगभग हमेशा होती है जो आप चाहते हैं।

अधिक सामान्यतः बोलते हुए, स्ट्रिंग्स के पास मूल्य शब्दार्थ है । यह मूल्य प्रकारों की तुलना में अधिक सामान्य अवधारणा है, जो कि C # विशिष्ट कार्यान्वयन विवरण है। मान प्रकार में मूल्य शब्दार्थ होते हैं, लेकिन संदर्भ प्रकार में मान शब्दार्थ भी हो सकते हैं। जब एक प्रकार का मूल्य शब्दार्थ होता है, तो आप वास्तव में यह नहीं बता सकते हैं कि अंतर्निहित कार्यान्वयन एक संदर्भ प्रकार या मूल्य प्रकार है, इसलिए आप विचार कर सकते हैं कि कार्यान्वयन विस्तार।


मूल्य प्रकार और संदर्भ प्रकारों के बीच अंतर वास्तव में प्रदर्शन के बारे में नहीं है। यह इस बारे में है कि एक चर में एक वास्तविक वस्तु होती है या किसी वस्तु का संदर्भ होता है। एक स्ट्रिंग संभवतः एक मूल्य प्रकार नहीं हो सकता है क्योंकि एक स्ट्रिंग का आकार चर है; इसे मूल्य प्रकार होने के लिए स्थिर रहने की आवश्यकता होगी; प्रदर्शन का इससे कोई लेना-देना नहीं है। संदर्भ प्रकार भी महंगे नहीं हैं।
16

2
@ सामान्य: एक स्ट्रिंग का आकार स्थिर है।
जैक्सबी

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

1
@ सामान्य: एक सरणी का आकार स्थिर है।
जाकबीस

1
एक बार जब आप एक सरणी बना लेते हैं तो इसका आकार स्थिर होता है, लेकिन पूरी दुनिया में सभी सरणियाँ बिल्कुल एक ही आकार की नहीं होती हैं। यही मेरा सवाल है। एक स्ट्रिंग के लिए एक मूल्य प्रकार होने के लिए अस्तित्व में सभी तारों को बिल्कुल एक ही आकार की आवश्यकता होगी, क्योंकि यह कैसे मान प्रकार .NET में डिज़ाइन किए गए हैं। यह वास्तव में एक मूल्य होने से पहले ऐसे मूल्य प्रकारों के लिए भंडारण स्थान आरक्षित करने में सक्षम होने की आवश्यकता है , इसलिए आकार को संकलन समय पर पता होना चाहिए । इस stringप्रकार के लिए कुछ निश्चित आकार के चार बफर की आवश्यकता होगी, जो प्रतिबंधात्मक और अत्यधिक अक्षम दोनों होंगे।
३० पर

16

यह एक पुराने प्रश्न का देर से उत्तर है, लेकिन अन्य सभी उत्तर उस बिंदु को याद कर रहे हैं, जो यह है कि .NET में 2005 में .NET 2.0 तक जेनेरिक नहीं था।

Stringमान प्रकार के बजाय एक संदर्भ प्रकार है क्योंकि यह Microsoft के लिए यह सुनिश्चित करने के लिए महत्वपूर्ण था कि स्ट्रिंग को गैर-सामान्य संग्रह में सबसे कुशल तरीके से संग्रहीत किया जा सकता है , जैसे कि System.Collections.ArrayList

गैर-जेनेरिक संग्रह में मूल्य-प्रकार को संग्रहीत करने के लिए उस प्रकार के एक विशेष रूपांतरण की आवश्यकता होती objectहै जिसे बॉक्सिंग कहा जाता है। जब CLR एक वैल्यू टाइप करता है, तो यह वैल्यू को एक के अंदर लपेटता है System.Objectऔर उसे प्रबंधित हीप पर स्टोर करता है।

संग्रह से मूल्य पढ़ना उलटा ऑपरेशन की आवश्यकता है जिसे अनबॉक्सिंग कहा जाता है।

बॉक्सिंग और अनबॉक्सिंग दोनों में गैर-नगण्य लागत होती है: बॉक्सिंग के लिए अतिरिक्त आवंटन की आवश्यकता होती है, अनबॉक्सिंग के लिए टाइप चेकिंग की आवश्यकता होती है।

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

यदि जेनेरिक पहले दिन से मौजूद था, तो मुझे लगता है कि मूल्य प्रकार के रूप में स्ट्रिंग होने से शायद बेहतर समाधान हो सकता है, सरल शब्दार्थ के साथ, बेहतर मेमोरी उपयोग और बेहतर कैश लोकेलिटी। एक List<string>छोटे से तार से युक्त, स्मृति का एक एकल सन्निहित ब्लॉक हो सकता है।


मेरा, इस उत्तर के लिए धन्यवाद! मैं ढेर और स्टैक आवंटन के बारे में बातें कहते हुए अन्य सभी उत्तरों को देख रहा हूं, जबकि स्टैक एक कार्यान्वयन विवरण है । सब के बाद, stringअपने आकार और charवैसे भी सरणी के लिए केवल एक सूचक होता है, इसलिए यह "विशाल मूल्य प्रकार" नहीं होगा। लेकिन यह इस डिजाइन निर्णय का एक सरल, प्रासंगिक कारण है। धन्यवाद!
V0ldek

8

न केवल तार अपरिवर्तनीय संदर्भ प्रकार हैं। बहु-कलाकारों के प्रतिनिधि भी। इसीलिए लिखना सुरक्षित है

protected void OnMyEventHandler()
{
     delegate handler = this.MyEventHandler;
     if (null != handler)
     {
        handler(this, new EventArgs());
     }
}

मुझे लगता है कि तार अपरिवर्तनीय हैं क्योंकि यह उनके साथ काम करने और स्मृति आवंटित करने के लिए सबसे सुरक्षित तरीका है। वे मूल्य प्रकार क्यों नहीं हैं? पिछले लेखक स्टैक आकार आदि के बारे में सही हैं। मैं यह भी जोड़ूंगा कि जब आप प्रोग्राम में एक ही निरंतर स्ट्रिंग का उपयोग करते हैं तो एक संदर्भ प्रकार असेंबली के आकार को बचाने की अनुमति देता है। यदि आप परिभाषित करते हैं

string s1 = "my string";
//some code here
string s2 = "my string";

संभावना है कि "मेरी स्ट्रिंग" स्थिरांक के दोनों उदाहरण केवल एक बार आपकी विधानसभा में आवंटित किए जाएंगे।

यदि आप सामान्य संदर्भ प्रकार की तरह स्ट्रिंग्स का प्रबंधन करना चाहते हैं, तो स्ट्रिंग को एक नए स्ट्रिंगबुलस्टल (स्ट्रिंग एस) के अंदर रखें। या मेमोरीस्ट्रीम का उपयोग करें।

यदि आप एक पुस्तकालय बनाने के लिए हैं, जहां आप अपने कार्यों में एक विशाल तार के पारित होने की उम्मीद करते हैं, या तो एक स्ट्रिंगर के रूप में या स्ट्रीम के रूप में एक पैरामीटर को परिभाषित करें।


1
अपरिवर्तनीय संदर्भ-प्रकार के बहुत सारे उदाहरण हैं। और स्ट्रिंग उदाहरण कर रहे हैं, वह यह है कि वास्तव में बहुत-बहुत वर्तमान कार्यान्वयन के तहत गारंटी - तकनीकी रूप से यह प्रति है मॉड्यूल (नहीं प्रति-विधानसभा) - लेकिन यह है कि लगभग हमेशा एक ही बात है ...
मार्क Gravell

5
अंतिम बिंदु फिर से करें: यदि आप एक बड़ी स्ट्रिंग को पास करने की कोशिश कर रहे हैं, तो StringBuilder मदद नहीं करता है (क्योंकि यह वास्तव में वैसे भी एक स्ट्रिंग के रूप में कार्यान्वित किया जाता है) - स्ट्रिंग स्ट्रिंग कई बार हेरफेर करने के लिए उपयोगी है ।
मार्क ग्रेवेल

क्या यू का मतलब डेलीगेट हैंडलर था, हिटलर नहीं? (क्षमा करने के लिए खेद है .. लेकिन यह एक बहुत (आम नहीं) उपनाम के करीब है मुझे पता है ....)
शुद्ध।

6

इसके अलावा, जिस तरह से तार लगाए गए हैं (प्रत्येक प्लेटफॉर्म के लिए अलग) और जब आप उन्हें एक साथ सिलाई करना शुरू करते हैं। एक का उपयोग कर की तरह StringBuilder। यह आपके लिए कॉपी करने के लिए एक बफर आवंटित करता है, एक बार जब आप अंत तक पहुँचते हैं, तो यह आपके लिए और भी अधिक मेमोरी आवंटित करता है, इस उम्मीद में कि यदि आप एक बड़े संघटन प्रदर्शन में बाधा नहीं डालेंगे।

शायद जॉन स्कीट यहाँ मदद कर सकता है?


5

यह मुख्य रूप से एक प्रदर्शन का मुद्दा है।

स्ट्रिंग्स होने से कोड लिखने पर LIKE वैल्यू टाइप में मदद मिलती है, लेकिन इसे BE होने से वेल्यू टाइप बहुत बड़ा परफॉर्मेंस हिट होगा।

गहराई से देखने के लिए, .net ढांचे में तार पर एक अच्छे लेख पर एक नज़र डालें ।


3

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


यह एक टिप्पणी होनी चाहिए
ρяσѕρ beя K

पीपीएल के लिए समझने में आसान c #
लंबी

2

आप कैसे कह सकते हैं कि stringएक संदर्भ प्रकार है? मुझे यकीन नहीं है कि यह मायने रखता है कि इसे कैसे लागू किया जाता है। C # में स्ट्रिंग्स अपरिवर्तनीय हैं ताकि आपको इस समस्या के बारे में चिंता न करनी पड़े।


यह एक संदर्भ प्रकार है (मेरा मानना ​​है) क्योंकि यह System.ValueType से MSDN रिमार्क्स ऑन सिस्टम से नहीं निकलता है ।ValueType: डेटा प्रकारों को मूल्य प्रकार और संदर्भ प्रकारों में अलग किया जाता है। मान प्रकार या तो एक संरचना में स्टैक-आबंटित या आवंटित इनलाइन हैं। संदर्भ प्रकार ढेर-आवंटित हैं।
डेवि Dav

दोनों संदर्भ और मूल्य प्रकार अंतिम आधार वर्ग ऑब्जेक्ट से प्राप्त होते हैं। ऐसे मामलों में जहां किसी वस्तु की तरह व्यवहार करने के लिए एक मूल्य प्रकार के लिए आवश्यक है, एक रैपर जो मान प्रकार बनाता है जैसे संदर्भ ऑब्जेक्ट को ढेर पर आवंटित किया जाता है, और मूल्य प्रकार के मूल्य को इसमें कॉपी किया जाता है।
डेवि

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

2

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

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

जहाँ तक "==": जैसा कि आपने कहा "==" एक ऑपरेटर अधिभार है, और फिर से इसे स्ट्रिंग्स के साथ काम करते समय फ्रेमवर्क को अधिक उपयोगी बनाने के लिए एक बहुत अच्छे कारण के लिए लागू किया गया था।


मुझे लगता है कि मूल्य प्रकार परिभाषा से अपरिवर्तनीय नहीं हैं, लेकिन सबसे अच्छा अभ्यास यह सुझाव देता है कि उन्हें अपना खुद का निर्माण करते समय होना चाहिए। मैंने कहा कि विशेषताओं, न कि मूल्य प्रकारों के गुण, जो मेरे लिए इसका मतलब है कि अक्सर मूल्य प्रकार ये प्रदर्शित करते हैं, लेकिन जरूरी नहीं कि परिभाषा के अनुसार
डेवी

5
@WebMatrix, @ Davy8: आदिम प्रकार (इंट, डबल, बूल, ...) अपरिवर्तनीय हैं।
जसो

1
@ जेसन, मैंने सोचा था कि अपरिवर्तनीय शब्द ज्यादातर वस्तुओं (संदर्भ प्रकारों) पर लागू होते हैं, जो आरंभीकरण के बाद बदल नहीं सकते हैं, जैसे तार जब मूल्य बदलते हैं, तो आंतरिक रूप से एक स्ट्रिंग का एक नया उदाहरण बनाया जाता है, और मूल वस्तु अपरिवर्तित रहती है। यह मूल्य प्रकारों पर कैसे लागू होता है?
वेबमैट्रिक्स

8
किसी तरह, "int n = 4; n = 9;" में, यह नहीं है कि आपका अंतर चर "स्थिर" है, "स्थिर" के अर्थ में; यह है कि मान 4 अपरिवर्तनीय है, यह 9 में नहीं बदलता है। आपका इंट चर "n" में पहले 4 का मान है और फिर एक अलग मान है, 9; लेकिन मूल्य स्वयं अपरिवर्तनीय हैं। सच कहूं, तो मेरे लिए यह wtf के बहुत करीब है।
डैनियल डारानास

1
+1। जब वे काफी सरलता से नहीं होते हैं, तो मैं इस "स्ट्रिंग्स प्रकार के मूल्य" सुनने से बीमार हो जाता हूं।
जॉन हन्ना

1

स्ट्रिंग्स कैरेक्टर सरणियों से बने होते हैं बस के रूप में सरल नहीं है। मैं चरित्र सरणियों के रूप में तार को देखता हूं []। इसलिए वे ढेर पर हैं क्योंकि संदर्भ स्मृति स्थान ढेर पर संग्रहीत है और ढेर पर सरणी के स्मृति स्थान की शुरुआत को इंगित करता है। स्ट्रिंग आकार आवंटित होने से पहले ज्ञात नहीं है ... ढेर के लिए एकदम सही है।

यही कारण है कि एक स्ट्रिंग वास्तव में अपरिवर्तनीय है क्योंकि जब आप इसे बदलते हैं, भले ही यह उसी आकार का हो, जिसे कंपाइलर को पता नहीं है और उसे एक नई सरणी आवंटित करनी है और वर्णों को पदों में असाइन करना है। यह समझ में आता है कि अगर आप स्ट्रिंग्स को एक तरह से सोचते हैं, तो भाषा आपको मक्खी पर मेमोरी आवंटित करने से बचाती है (प्रोग्रामिंग की तरह सी पढ़ें)


1
"स्ट्रिंग आकार आवंटित होने से पहले ज्ञात नहीं है" - यह सीएलआर में गलत है।
कोडकाइज़न

-1

अभी तक एक और रहस्यमय डाउन-वोट प्राप्त करने के जोखिम में ... तथ्य यह है कि कई स्टैक और मेमोरी का उल्लेख मूल्य प्रकार और आदिम प्रकार के संबंध में करते हैं क्योंकि उन्हें माइक्रोप्रोसेसर में एक रजिस्टर में फिट होना चाहिए। यदि आप एक रजिस्टर से अधिक बिट्स लेते हैं, तो आप स्टैक से / को कुछ धक्का या पॉप नहीं कर सकते हैं .... निर्देश हैं, उदाहरण के लिए "पॉप ईएक्स" - क्योंकि ईएक्स 32-बिट सिस्टम पर 32 बिट्स चौड़ा है।

फ्लोटिंग-पॉइंट आदिम प्रकार एफपीयू द्वारा नियंत्रित किए जाते हैं, जो कि 80 बिट्स चौड़ा है।

आदिम प्रकार की परिभाषा को मानने के लिए ओओपी भाषा होने से पहले यह सब तय किया गया था और मेरा मानना ​​है कि मूल्य प्रकार एक शब्द है जो विशेष रूप से ओओपी भाषाओं के लिए बनाया गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.