मैं अपने जवाब में किए गए एक विशेष बिंदु एरिक लिपर्ट के बारे में विस्तार से बताना चाहता हूं और किसी विशेष अवसर पर स्पॉटलाइट डालता हूं जिसे किसी और ने नहीं छुआ है। एरिक ने कहा:
[...] एक असाइनमेंट लगभग हमेशा उस मान को पीछे छोड़ देता है जिसे अभी एक रजिस्टर में सौंपा गया था।
मैं यह कहना चाहता हूं कि असाइनमेंट हमेशा उस मूल्य को पीछे छोड़ देगा, जिसे हमने अपने बाएं ऑपरेंड को असाइन करने की कोशिश की थी। सिर्फ "लगभग हमेशा" नहीं। लेकिन मुझे नहीं पता क्योंकि मुझे नहीं मिला कि इस मुद्दे को प्रलेखन में टिप्पणी की गई थी। यह सैद्धांतिक रूप से एक बहुत प्रभावी कार्यान्वित प्रक्रिया हो सकती है जो "पीछे रह जाती है" और बाएं ऑपरेंड का पुनर्मूल्यांकन न करे, लेकिन क्या यह कुशल है?
इस सूत्र के उत्तर में निर्मित सभी उदाहरणों के लिए 'कुशल' हाँ। लेकिन प्रापर्टी और इंडेक्सर्स के मामले में कुशल, जो एक्सेस प्राप्त करते हैं और एक्सेसर्स सेट करते हैं? हर्गिज नहीं। इस कोड पर विचार करें:
class Test
{
public bool MyProperty { get { return true; } set { ; } }
}
यहां हमारे पास एक संपत्ति है, जो एक निजी चर के लिए एक आवरण भी नहीं है। जब भी उसे बुलाया जाएगा, वह सच्चा लौटेगा, जब भी कोई अपना मूल्य निर्धारित करने की कोशिश करेगा वह कुछ नहीं करेगा। इस प्रकार जब भी इस संपत्ति का मूल्यांकन किया जाता है, वह सत्य होगी। चलिए देखते हैं क्या होता है:
Test test = new Test();
if ((test.MyProperty = false) == true)
Console.WriteLine("Please print this text.");
else
Console.WriteLine("Unexpected!!");
लगता है क्या यह प्रिंट? यह प्रिंट करता है Unexpected!!। जैसा कि यह पता चला है, सेट एक्सेसर वास्तव में कहा जाता है, जो कुछ भी नहीं करता है। लेकिन इसके बाद, गेट एक्सेसर को कभी नहीं बुलाया जाता है। असाइनमेंट केवल उस falseमूल्य को पीछे छोड़ देता है जिसे हमने अपनी संपत्ति को असाइन करने की कोशिश की थी। और यह falseमान है कि यदि कथन का मूल्यांकन होता है।
मैं एक वास्तविक दुनिया उदाहरण के साथ समाप्त करूँगा जिसने मुझे इस मुद्दे पर शोध किया। मैंने एक इंडेक्सर बनाया जो एक संग्रह के लिए एक सुविधाजनक आवरण था ( List<string>) जो कि मेरा एक वर्ग एक निजी चर के रूप में था।
इंडेक्सर को भेजा गया पैरामीटर एक स्ट्रिंग था, जिसे मेरे संग्रह में एक मूल्य के रूप में माना जाना था। यदि यह मान सूची में मौजूद है या नहीं, तो एक्सेस एक्सेसर केवल सही या गलत लौटाएगा। इस प्रकार प्राप्तकर्ता उपयोग करने का एक और तरीका थाList<T>.Contains विधि ।
यदि अनुक्रमणिका के सेट एक्सेसर को एक तर्क के रूप में स्ट्रिंग के साथ बुलाया गया था और सही ऑपरेंड एक बूल था true, तो वह उस पैरामीटर को सूची में जोड़ देगा। लेकिन अगर वही पैरामीटर एक्सेसर को भेजा गया था और सही ऑपरेंड एक बूल था false, तो वह सूची से तत्व को हटा देगा। इस प्रकार सेट एक्सेसर दोनों के लिए एक सुविधाजनक विकल्प के रूप में इस्तेमाल किया गया था List<T>.AddऔरList<T>.Remove ।
मुझे लगा कि मेरे पास गेटवे के रूप में लागू किए गए अपने तर्क के साथ सूची को लपेटकर एक साफ और कॉम्पैक्ट "एपीआई" है। अकेले एक इंडेक्सर की मदद से मैं कीस्ट्रोक्स के कुछ सेट के साथ कई काम कर सकता था। उदाहरण के लिए, मैं अपनी सूची में मान जोड़ने और यह सत्यापित करने का प्रयास कैसे कर सकता हूं कि यह वहां है? मैंने सोचा कि यह आवश्यक कोड की एकमात्र पंक्ति थी:
if (myObject["stringValue"] = true)
; // Set operation succeeded..!
लेकिन जैसा कि मेरे पहले के उदाहरण से पता चलता है, एक्सेस एक्सेसर जो यह देखने वाला है कि क्या वास्तव में मूल्य सूची में है भी नहीं। trueमूल्य हमेशा पीछे प्रभावी रूप से नष्ट जो कुछ भी तर्क मैं अपने get एक्सेसर में लागू किया था छोड़ दिया गया था।