सार्वजनिक उत्परिवर्तित क्षेत्रों या गुणों वाली संरचनाएं बुराई नहीं हैं।
संरचना विधियां (संपत्ति बसने वालों से अलग) जो "इस" को म्यूट करती हैं, केवल इसलिए कि यह .net उन्हें उन तरीकों से अलग करने का साधन प्रदान नहीं करता है जो नहीं करते हैं। संरचना विधियाँ जो "इस" को उत्परिवर्तित नहीं करती हैं, उन्हें केवल रक्षात्मक प्रतिलिपि की आवश्यकता के बिना केवल-पढ़ी गई संरचना पर भी अदृश्य होना चाहिए। जो विधियाँ "यह" करती हैं, उन्हें केवल-पढ़ने के लिए संरचितों पर लागू नहीं किया जाना चाहिए। चूँकि .net उन संरचनात्मक विधियों को मना नहीं करना चाहता जो "इसे" को केवल-पढ़ी हुई संरचना पर लागू होने से संशोधित नहीं करती हैं, लेकिन केवल-पढ़ी हुई संरचना को उत्परिवर्तित करने की अनुमति नहीं देना चाहती हैं, यह रक्षात्मक रूप से पढ़ी गई रचनाओं की प्रतिलिपि बनाती है। केवल संदर्भ, यकीनन दोनों दुनिया के सबसे खराब हो रहे हैं।
केवल-पढ़ने के संदर्भों में स्व-उत्परिवर्तन विधियों की हैंडलिंग के साथ समस्याओं के बावजूद, उत्परिवर्तनीय संरचनाएं अक्सर शब्दार्थों को उत्परिवर्ती वर्ग प्रकारों से बेहतर प्रदान करती हैं। निम्नलिखित तीन विधि हस्ताक्षर पर विचार करें:
संरचना PointyStruct {सार्वजनिक int x, y, z;};
वर्ग PointyClass {सार्वजनिक int x, y, z;};
शून्य विधि 1 (पॉइन्टीस्ट्रक्ट फू);
शून्य मेथड 2 (रिफ पॉइन्टीस्ट्रक्ट फू);
void Method3 (PointyClass foo);
प्रत्येक विधि के लिए, निम्नलिखित प्रश्नों के उत्तर दें:
- यह मानते हुए कि विधि किसी भी "असुरक्षित" कोड का उपयोग नहीं करती है, क्या यह फू को संशोधित कर सकता है?
- यदि विधि कहे जाने से पहले 'फू' का कोई बाहरी संदर्भ मौजूद नहीं है, तो क्या बाहर का संदर्भ मौजूद हो सकता है?
उत्तर:
प्रश्न 1::
Method1()
नहीं (स्पष्ट इरादा)
Method2()
: हाँ (स्पष्ट इरादा)
Method3()
: हाँ (अनिश्चित इरादे)
प्रश्न 2
Method1()
:: नहीं
Method2()
: नहीं (जब तक असुरक्षित)
Method3()
: हाँ
Method1 फू को संशोधित नहीं कर सकता है, और कभी भी संदर्भ नहीं मिलता है। Method2 को फू के लिए एक अल्पकालिक संदर्भ मिलता है, जिसका उपयोग यह किसी भी क्रम में, किसी भी क्रम में, किसी भी समय foo के फ़ील्ड को संशोधित करने के लिए कर सकता है, लेकिन यह उस संदर्भ को जारी नहीं रख सकता। Method2 रिटर्न से पहले, जब तक कि यह असुरक्षित कोड का उपयोग नहीं करता है, तब तक इसके 'फू' संदर्भ से बनी कोई भी और सभी प्रतियां गायब हो गई होंगी। Method3, Method2 के विपरीत, फू को प्रोमिस्युली-शार्बल रेफरेंस मिलता है, और इसके साथ क्या हो सकता है, यह कोई नहीं बता रहा है। यह फू को बिल्कुल नहीं बदल सकता है, यह फू को बदल सकता है और फिर वापस आ सकता है, या हो सकता है कि यह किसी अन्य धागे को फू का संदर्भ दे सकता है जो भविष्य के कुछ मनमाने तरीके से इसे मनमाने तरीके से बदल सकता है।
संरचनाओं की सरणियाँ अद्भुत शब्दार्थ प्रदान करती हैं। RectArray [500] प्रकार के आयत को देखते हुए, यह स्पष्ट और स्पष्ट है कि प्रतिलिपि तत्व 123 से तत्व 456 तक और फिर कुछ समय बाद तत्व 123 की चौड़ाई को निर्धारित किए बिना, तत्व को 456 पर सेट किए बिना। "RectArray [432] = RectArray [321 ]; ...; RectArray [123] .Width = 555; "। यह जानकर कि आयत एक पूर्णांक क्षेत्र के साथ एक संरचना है जिसे चौड़ाई कहा जाता है, जो उपरोक्त सभी कथनों के बारे में जानने के लिए सभी को बताएगा।
अब मान लें कि रेक्टक्लास आयतों के समान ही एक वर्ग था और एक रेक्टक्लास के RectClassArray [500] पर समान संचालन करना चाहता था। संभवतः सरणी को RableClass की उत्परिवर्तित वस्तुओं के लिए 500 पूर्व-प्रारंभिक अपरिवर्तनीय संदर्भों को धारण करना चाहिए। उस स्थिति में, उचित कोड कुछ "RectClassArray [321] .SetBounds (RectClassArray [456]) जैसा होगा; ...; RectClassArray [321] .X = 555;"। शायद सरणी को ऐसे उदाहरणों को धारण करने के लिए माना जाता है जो बदलने नहीं जा रहे हैं, इसलिए उचित कोड "RectClassArray [321] = RectClassArray [456] ...; RectClassArray [321] = New RectClass (RectClassArray [321) की तरह होगा; ]); रेक्टक्लासअरे [321] .X = 555; " यह जानने के लिए कि किसी को क्या करना है, दोनों को RectClass के बारे में बहुत कुछ जानना होगा (जैसे कि यह एक कॉपी कंस्ट्रक्टर, एक कॉपी-मेथड विधि आदि का समर्थन करता है)। ) और सरणी का इच्छित उपयोग। एक संरचना का उपयोग करने के रूप में कहीं भी साफ नहीं है।
यह सुनिश्चित करने के लिए कि किसी सरणी के अलावा किसी कंटेनर श्रेणी के लिए दुर्भाग्य से कोई अच्छा तरीका नहीं है, जो किसी संरचना सरणी के स्वच्छ शब्दार्थ को प्रस्तुत करता है। सबसे अच्छा एक कर सकता है, अगर कोई एक संग्रह को उदाहरण के लिए एक स्ट्रिंग के साथ अनुक्रमित करना चाहता था, तो संभवतः एक सामान्य "ActOnItem" विधि की पेशकश करेगा, जो सूचकांक के लिए एक स्ट्रिंग को स्वीकार करेगा, एक सामान्य पैरामीटर, और एक प्रतिनिधि जो पारित होगा। जेनेरिक पैरामीटर और संग्रह आइटम दोनों के संदर्भ में। यह लगभग समान शब्दार्थों को संरचनात्मक सरणियों के रूप में अनुमति देता है, लेकिन जब तक कि vb.net और C # लोगों को एक अच्छा वाक्यविन्यास पेश करने के लिए पीछा नहीं किया जा सकता है, तब तक कोड क्लिंक-दिखने वाला होता है, भले ही यह यथोचित प्रदर्शन हो (एक सामान्य पैरामीटर पास करना) एक स्थिर प्रतिनिधि के उपयोग के लिए अनुमति दें और किसी भी अस्थायी वर्ग उदाहरण बनाने की आवश्यकता से बचें)।
व्यक्तिगत रूप से, मुझे घृणा करने वाले एरिक लिपर्ट एट अल पर गर्व है। उत्परिवर्तनीय मूल्य प्रकारों के बारे में बताया। वे सभी स्थान पर उपयोग किए जाने वाले उचित संदर्भ प्रकारों की तुलना में बहुत अधिक स्वच्छ शब्दार्थ प्रदान करते हैं। मूल्य प्रकारों के लिए .net के समर्थन के साथ कुछ सीमाओं के बावजूद, ऐसे कई मामले हैं जहां परस्पर मूल्य प्रकार किसी भी अन्य प्रकार की इकाई की तुलना में बेहतर फिट हैं।
int
एस,bool
एस का दावा करने जैसा है , और अन्य सभी मूल्य प्रकार बुराई हैं। उत्परिवर्तन और अपरिवर्तनीयता के मामले हैं। उन मामलों में डेटा की भूमिका पर टिका हुआ है, स्मृति आवंटन / साझाकरण का प्रकार नहीं।