क्या गुणों का दुष्प्रभाव होना चाहिए


19

C # में गुण होने के कारण इसके राज्यों में परिवर्तन की सूचना देने के साइड इफेक्ट्स हैं?

मैंने कई अलग-अलग तरीकों से उपयोग किए जाने वाले गुणों को देखा है। उन संपत्तियों से, जो पहली बार उन गुणों तक पहुँचेंगे जो उन गुणों तक पहुँचते हैं जिनके बड़े पैमाने पर दुष्प्रभाव होते हैं जैसे किसी भिन्न पृष्ठ पर पुनर्निर्देशित करना।


3
आह मुझे एक प्रासंगिक एसओ प्रश्न मिल जाए। 1 सेकंड stackoverflow.com/questions/2451910/... stackoverflow.com/questions/2784934/... stackoverflow.com/questions/582680/... stackoverflow.com/questions/694711/...
नौकरी

1
@ नौकरी के निष्कर्षों के बीच, मुझे C # में गुणों का उपयोग करने से क्यों बचना चाहिए? उर्फ जेफरी रिक्टर की राय इस सवाल के लिए बहुत प्रासंगिक है।
rwong

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

यद्यपि यह निर्माणकर्ताओं से संबंधित है, यह भी प्रासंगिक है: programmers.stackexchange.com/a/164255/1996
जिम जी।

जवाबों:


40

मुझे लगता है कि आप पढ़ रहे हैं केवल गुण, या कम से कम संपत्ति पाने वालों के बारे में बात कर रहे हैं , क्योंकि एक संपत्ति सेटर लगभग हर उदाहरण में, साइड-इफेक्ट होने वाला है। अन्यथा यह बहुत उपयोगी नहीं है।

सामान्य तौर पर, एक अच्छा डिजाइन कम से कम आश्चर्य के सिद्धांत का पालन ​​करता है । ऐसी चीजें न करें जो कॉल करने वाले आपसे करने की उम्मीद नहीं कर रहे हैं, खासकर अगर उन चीजों से भविष्य के परिणाम बदल सकते हैं ।

सामान्य तौर पर , इसका मतलब है कि संपत्ति पाने वालों पर दुष्प्रभाव नहीं होना चाहिए।

हालांकि , हम "साइड इफेक्ट" से क्या मतलब है, इसके बारे में सावधान रहें ।

एक दुष्प्रभाव , तकनीकी रूप से, राज्य के किसी भी संशोधन है। यह सार्वजनिक रूप से सुलभ राज्य हो सकता है, या ... यह पूरी तरह से निजी राज्य हो सकता है।

आलसी / स्थगित लोडर राज्य का एक उदाहरण है जो लगभग विशेष रूप से निजी है। जब तक यह उस संसाधन को मुक्त करने के लिए कॉलर की जिम्मेदारी नहीं है, तब तक आप वास्तव में आस्थगित आरंभीकरण का उपयोग करके आश्चर्य और जटिलता को कम कर रहे हैं । एक कॉलर को आमतौर पर आंतरिक संरचना के प्रारंभ के स्पष्ट संकेत की उम्मीद नहीं होती है। तो, आलसी आरंभीकरण उपरोक्त सिद्धांत का उल्लंघन नहीं करता है।

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

इसलिए मैं प्रतिबंध निम्न के थोड़ा ढीला होगा: संपत्ति पढ़ता नहीं होना चाहिए दिखाई दुष्प्रभाव या साइड इफेक्ट है जो उनके अर्थ विज्ञान बदल

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

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


2
+1 - अधिक जटिल मामलों सहित एक अच्छा पूर्ण उत्तर जो "चाहिए" को "चाहिए ... को छोड़कर ..." में बदल जाता है
जल्‍दी से अनजाने

एक गेटर पर स्वीकार्य साइड इफेक्ट का एक और उदाहरण: एक लॉगिंग फ़ंक्शन।
लोरेन Pechtel

5

मैं आपके प्रश्न का उत्तर एक प्रश्न के साथ दूंगा: जब आप किसी प्रपत्र की चौड़ाई गुण को संशोधित करते हैं तो क्या होता है?

बस मेरे सिर के ऊपर से, यह होगा:

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

(अस्वीकरण: मैं डेल्फी डेवलपर हूं। .NET डेवलपर नहीं। यह सी # के लिए 100% सटीक नहीं हो सकता है, लेकिन मुझे यकीन है कि यह बहुत करीब है, विशेष रूप से यह देखते हुए कि मूल .NET फ्रेमवर्क डेल्फी पर कितना आधारित था।)

ये सभी "साइड इफेक्ट्स" तब होते हैं जब आप एक फॉर्म पर चौड़ाई की संपत्ति बदलते हैं। क्या उनमें से कोई भी अनुचित या गलत लगता है?


जब तक यह खुद को बुलाता हुआ अनंत लूप में नहीं जाता है। इससे बचने के लिए, प्रत्येक "परिवर्तन" को कम से कम तीन घटनाओं में मैप किया जाएगा: एक परिवर्तन से पहले निकाल दिया गया था, एक परिवर्तन के दौरान निकाल दिया गया था, और एक समाप्त होने के बाद निकाल दिया गया था।
rwong

5

Microsoft डिज़ाइन नियमों पर एक नज़र डालें , विशेष रूप से उनमें से एक:

CA1024: उन गुणों का उपयोग करें जहाँ उपयुक्त हों

... एक विधि एक अच्छा उम्मीदवार बनने के लिए एक संपत्ति है अगर इनमें से एक स्थिति मौजूद है:

  • कोई तर्क नहीं देता है और किसी वस्तु की राज्य की जानकारी लौटाता है।
  • किसी वस्तु की स्थिति का कुछ भाग निर्धारित करने के लिए एक एकल तर्क को स्वीकार करता है।

गुण व्यवहार करना चाहिए जैसे कि वे क्षेत्र हैं; यदि विधि नहीं कर सकती है, तो उसे किसी संपत्ति में नहीं बदलना चाहिए। निम्नलिखित स्थितियों में गुण की तुलना में तरीके बेहतर हैं:

  • विधि एक समय लेने वाली कार्रवाई करती है। किसी क्षेत्र का मान सेट करने या प्राप्त करने के लिए आवश्यक समय की तुलना में यह विधि बहुत धीमी है।
  • विधि रूपांतरण करती है। किसी फ़ील्ड तक पहुँचने से डेटा का एक परिवर्तित संस्करण वापस नहीं आता है जिसे वह संग्रहीत करता है।
  • गेट विधि का एक दुष्प्रभाव है। किसी क्षेत्र का मूल्य प्राप्त करने से कोई दुष्प्रभाव नहीं होता है।
  • निष्पादन का क्रम महत्वपूर्ण है। किसी फ़ील्ड का मान सेट करना अन्य ऑपरेशनों की घटना पर निर्भर नहीं करता है।
  • उत्तराधिकार में दो बार विधि को कॉल करना अलग परिणाम बनाता है।
  • विधि स्थिर है, लेकिन एक ऑब्जेक्ट लौटाता है जिसे कॉलर द्वारा बदला जा सकता है। किसी फ़ील्ड के मान को पुनः प्राप्त करना कॉलर को फ़ील्ड द्वारा संग्रहीत डेटा को बदलने की अनुमति नहीं देता है।
  • विधि एक सरणी देता है ...

2

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

संपादित करें : ओह, एक और बात - एक घटना "फायरएक्सवायजेड चेंज!" (जैसे INotifyPropertyChanged) - बसने वालों पर ठीक है।


2

पहले उल्लेखित आलसी लोडिंग के अलावा लॉगिंग फ़ंक्शन का भी मामला है। ये दुर्लभ होगा लेकिन प्रश्न से बाहर नहीं होगा।


2

प्रोग्रामिंग में लगभग कोई निरपेक्षता नहीं है, आपके प्रश्न का उत्तर देने के लिए हमें वस्तुओं के कुछ वांछनीय गुणों को देखने की जरूरत है और देखें कि क्या हमारे मामले में लागू होने वाली कोई चीज है

  1. हम चाहते हैं कि कक्षाएं आसानी से परीक्षण योग्य हों।
  2. हम चाहते हैं कि कक्षाएं संगामिति का समर्थन करें
  3. हम चाहते हैं कि कक्षाएं तृतीय-पक्ष के लिए तर्क के लिए आसान हों

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

सामान्य रूप से अधिक दुष्प्रभाव एक वर्ग का परीक्षण करने के लिए अधिक कठिन होगा। अधिक माध्यमिक साइड इफेक्ट्स अधिक कठिन संगामना को संभालना होगा, लेकिन यह एक कठिन मुद्दा है जो शायद वैसे भी कुछ प्रमुख डिजाइन की आवश्यकता है।

बड़ा गोच शायद उन लोगों के लिए है जो आपकी कक्षा को "ब्लैक बॉक्स" मानते हैं, यह आसानी से उपलब्ध नहीं होगा कि कुछ राज्य सिर्फ इसलिए बदल गए हैं क्योंकि उन्होंने एक संपत्ति पढ़ी है या कुछ अन्य संपत्ति बदल गई है क्योंकि एक और बदलाव (जिसके कारण नेतृत्व हो सकता है) अद्यतन करने के लिए)।

इसलिए सामान्य तौर पर, हम चाहते हैं कि संपत्तियों के बारे में जितना संभव हो उतना आसान और सरल होना चाहिए, जो कि डिजाइन निर्णय में निहित है अन्यथा यह एक विधि होगी। एक अच्छा प्रोग्रामर हमेशा नियमों को तोड़ सकता है, बस यह सुनिश्चित करें कि आपके पास वास्तव में अच्छा कारण है :)

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