2009-05-26 17 views
8

मुझे आश्चर्य है कि अपरिवर्तनीयता को कैसे परिभाषित किया जाता है? यदि मूल्य सार्वजनिक के रूप में प्रकट नहीं होते हैं, तो संशोधित नहीं किया जा सकता है, तो यह पर्याप्त है?अपरिवर्तनीयता की वास्तविक परिभाषा?

क्या मूल्य के अंदर मूल्यों को संशोधित किया जा सकता है, न कि प्रकार के ग्राहक द्वारा?

या क्या कोई उन्हें केवल एक निर्माता के अंदर सेट कर सकता है? यदि हां, तो डबल प्रारंभिकरण के मामले में (this structs पर कीवर्ड, आदि का उपयोग कर) अभी भी अपरिवर्तनीय प्रकारों के लिए ठीक है?

मैं कैसे गारंटी दे सकता हूं कि प्रकार 100% अपरिवर्तनीय है?

उत्तर

23

यदि मूल्य सार्वजनिक रूप से प्रकट नहीं होते हैं, तो संशोधित नहीं किया जा सकता है, तो यह पर्याप्त है?

नहीं, क्योंकि आपको पढ़ने की पहुंच की आवश्यकता है।

क्या मूल्य प्रकार के अंदर संशोधित किया जा सकता है, प्रकार के ग्राहक द्वारा नहीं?

नहीं, क्योंकि यह अभी भी उत्परिवर्तन है।

या एक ही एक निर्माता के अंदर उन्हें सेट कर सकते हैं?

डिंग डिंग डिंग! अतिरिक्त अंक अपरिवर्तनीय प्रकार अक्सर तरीकों कि निर्माण और नए उदाहरणों लौटने के लिए, और यह भी अक्सर अतिरिक्त कंस्ट्रक्टर्स internal विशेष रूप से चिह्नित उन तरीकों के उपयोग के लिए है है के साथ।

मैं कैसे गारंटी दे सकता हूं कि यह प्रकार 100% अपरिवर्तनीय है?

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

+2

बस सब कुछ शामिल करने के बारे में ;-p –

+0

अरे मार्क, मुझे आश्चर्य है कि आप अपने हालिया अपरिवर्तनीय प्रश्नों पर आपको नहीं देख पाएंगे। अपरिवर्तनीयता मुझे आपको याद दिलाती है :) –

3

यहाँ विकिपीडिया (link)

से अचल स्थिति की परिभाषा है "में वस्तु उन्मुख और कार्यात्मक प्रोग्रामिंग, अपरिवर्तनीय वस्तु एक वस्तु जिसका राज्य के बाद यह बनाई गई है बदला नहीं जा सकता है।"

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

1

मैंने सीखा है अचल स्थिति यह है कि जब आप निर्माता में सब कुछ सेट और वस्तु के जीवनकाल के दौरान बाद में इसे संशोधित नहीं कर सकते।

1

अचल स्थिति की परिभाषा Google पर स्थित हो सकता है।

उदाहरण:

अपरिवर्तनीय - सचमुच, बदलने में सक्षम नहीं।
www.filosofia.net/materiales/rec/glosaen।htm

अपरिवर्तनीय डेटा संरचनाओं के संदर्भ में, ठेठ परिभाषा लिखने-बार पढ़ने के लिए कई, दूसरे शब्दों में, के रूप में आप कहते हैं, एक बार बनाया है, यह बदला नहीं जा सकता है।

कुछ ऐसे मामले हैं जो भूरे रंग के क्षेत्र में थोड़ा सा हैं। उदाहरण के लिए, .NET तारों को अपरिवर्तनीय माना जाता है, क्योंकि वे परिवर्तित नहीं हो सकते हैं, हालांकि, स्ट्रिंगबिल्डर आंतरिक रूप से स्ट्रिंग ऑब्जेक्ट को संशोधित करता है।

1

एक अपरिवर्तनीय अनिवार्य रूप से एक वर्ग है जो स्वयं को अपने कोड के भीतर से अंतिम रूप देने के लिए मजबूर करता है। एक बार यह वहां हो जाने के बाद, कुछ भी नहीं बदला जा सकता है। मेरे ज्ञान में, चीजें कन्स्ट्रक्टर में सेट की गई हैं और फिर यह है। मैं नहीं देखता कि अन्यथा कुछ अपरिवर्तनीय कैसे हो सकता है।

3

वहां बहुत सारे प्रश्न हैं। मैं व्यक्तिगत रूप से उनमें से प्रत्येक के जवाब देने की कोशिश करेंगे:

  • "मैं सोच रहा हूँ कैसे अचल स्थिति परिभाषित किया गया है?" - सीधे Wikipedia page (और एक पूरी तरह से सही/संक्षिप्त परिभाषा)

    से एक अपरिवर्तनीय वस्तु एक वस्तु जिसका राज्य के बाद यह

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

  • "क्या प्रकार के अंदर मूल्यों को संशोधित किया जा सकता है, न कि प्रकार के ग्राहक द्वारा?" - तकनीकी रूप से, इसे या तो अंदर या उपभोक्ता द्वारा संशोधित नहीं किया जा सकता है। प्रैटिस में, System.String (इस मामले के लिए एक संदर्भ प्रकार) जैसे प्रकार मौजूद हैं, जो लगभग सभी व्यावहारिक उद्देश्यों के लिए उत्परिवर्तनीय माना जा सकता है, हालांकि सिद्धांत में नहीं।

  • "या क्या कोई उन्हें केवल एक निर्माता के अंदर सेट कर सकता है?" - हां, सिद्धांत में केवल स्थान है जहां राज्य (चर) सेट किया जा सकता है।

  • "यदि हां, तो डबल आरंभीकरण के मामलों (, structs पर इस कीवर्ड का उपयोग कर आदि) में अभी भी ठीक अपरिवर्तनीय प्रकार के लिए है?" - हाँ, यह अभी भी पूरी तरह से ठीक है, क्योंकि यह प्रारंभिकरण (सृजन) प्रक्रिया का हिस्सा है, और यह पूरा होने तक इंस्टेंस वापस नहीं किया जाता है।

  • "मैं कैसे गारंटी दे सकता हूं कि यह प्रकार 100% अपरिवर्तनीय है?" - निम्नलिखित शर्तों को बीमा करना चाहिए। (कृपया कोई बताएं कि क्या मुझे याद आ रही है।)

    1. किसी भी चर का पर्दाफाश न करें। वे सभी private रखा जाना चाहिए (भी नहीं protected स्वीकार्य है, क्योंकि व्युत्पन्न वर्ग तो राज्य को संशोधित कर सकते है)।
    2. किसी भी इंस्टेंस विधियों को राज्य (चर) को संशोधित करने की अनुमति न दें। यह केवल निर्माता में किया जाना चाहिए, जबकि तरीकों के लिए एक विशेष निर्माता का उपयोग कर नए उदाहरण बना चाहिए अगर वे एक "संशोधित" वस्तु वापस जाने के लिए की आवश्यकता है।
    3. सभी सदस्यों को अवगत कराया जाता है कि (केवल पढ़ने के लिए के रूप में) या तरीकों द्वारा लौटाए खुद वस्तुओं अपरिवर्तनीय हो चाहिए।

    नोट: आप व्युत्पन्न प्रकारों की अपरिवर्तनीयता बीमा नहीं कर सकते हैं, क्योंकि वे नए चर परिभाषित कर सकते हैं। यह किसी भी प्रकार को चिह्नित करने का एक कारण है जिसे आप सुनिश्चित नहीं करना चाहते हैं कि यह sealed के रूप में अपरिवर्तनीय है ताकि कोई व्युत्पन्न वर्ग कोड में कहीं भी आपके बेस अपरिवर्तनीय प्रकार के रूप में नहीं माना जा सके।

आशा है कि मदद करता है।

+1

मैं इसे जोड़ दूंगा, अगर आप सदस्यों का पर्दाफाश करते हैं, तो शायद उन्हें अपरिवर्तनीय भी होना चाहिए ... –

+0

@ डेनिस: हाँ, मुझे पता था कि मुझे कुछ स्पष्ट याद आया। धन्यवाद! – Noldorin

+0

धन्यवाद। क्या होगा अगर कोई अपरिवर्तनीय वर्ग बनाने के लिए मेरी अपरिवर्तनीय कक्षा को लपेटता है? जैसा कि आप पॉइंट.एक्स का पर्दाफाश करते हैं, प्वाइंट.Y पढ़ने के लिए और वह परिवर्तनों को प्रतिबिंबित/अद्यतन करने के लिए उनका उपयोग करता है? किसी ने मुझे लोगों को सीलबंद कक्षाओं को बाईपास करने के लिए कहा। –

7

पिछले पोस्टर पहले से ही कह चुके हैं कि आपको अपने क्षेत्र में कन्स्ट्रक्टर में मान असाइन करना चाहिए और फिर अपने हाथों को बंद रखना चाहिए। लेकिन कभी-कभी ऐसा करने से आसान कहा जाता है। मान लें कि आपकी अपरिवर्तनीय वस्तु List<string> प्रकार की संपत्ति का खुलासा करती है। क्या उस सूची को बदलने की अनुमति है? और यदि नहीं, तो आप इसे कैसे नियंत्रित करेंगे?

एरिक लिपर्ट ने सी # में अपरिवर्तनीयता के बारे में अपने ब्लॉग में कई पदों को लिखा है जो आपको दिलचस्प लग सकता है: you find the first part here

+0

यह एक दिलचस्प सवाल है। क्या आप सूची को पढ़ सकते हैं? –

+4

यह exaclty पर निर्भर करता है कि आप किस प्रकार का पर्दाफाश करते हैं। एक सूची के साथ आप नहीं कर सकते हैं, लेकिन यदि आप ReadOnlyCollection का पर्दाफाश करते हैं तो आप शायद (मुझे इसके बारे में पर्याप्त जानकारी नहीं है कि यह केवल पढ़ने के लिए गारंटी है)। लेकिन नियमित सरणी भी उत्परिवर्तनीय हैं, इसलिए आपको वास्तव में ध्यान देने की आवश्यकता है कि आप किस प्रकार के अपरिवर्तनीय प्रकार में प्रकट होते हैं। श्री लिपर्ट को जोड़ने के लिए –

+0

+1: पी – Lucas

5

एक चीज जो मुझे लगता है कि इन सभी उत्तरों में याद किया जा सकता है यह है कि मुझे लगता है कि एक वस्तु को अपरिवर्तनीय माना जा सकता है भले ही उसका आंतरिक परिवर्तन बदलता है - जब तक कि आंतरिक परिवर्तन 'क्लाइंट' कोड के लिए दृश्यमान न हों।

उदाहरण के लिए, System.String कक्षा अपरिवर्तनीय है, लेकिन मुझे लगता है कि इसे एक उदाहरण के लिए हैश कोड को कैश करने की अनुमति होगी ताकि हैश को केवल GetHashCode() पर पहली कॉल पर गणना की जा सके। ध्यान दें कि जहां तक ​​मुझे पता है, System.String कक्षा नहीं है, लेकिन मुझे लगता है कि यह अभी भी अपरिवर्तनीय माना जा सकता है। बेशक इनमें से किसी भी बदलाव को थ्रेड-सुरक्षित तरीके से संभालना होगा (परिवर्तनों के अवलोकन करने योग्य पहलू को ध्यान में रखते हुए)।

हालांकि ईमानदार होने के लिए, मैं ऐसे कई कारणों के बारे में नहीं सोच सकता जो किसी को चाहिए या इस तरह की 'अदृश्य व्यवहार्यता' की आवश्यकता है।

+0

अच्छा बिंदु माइकल। –

+2

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

+0

सी ++ कीवर्ड "mutable" की तुलना करें, जो कक्षा के सदस्य को निर्दिष्ट करता है जिसे एक कॉन्स ऑपरेशन में भी बदला जा सकता है। यह आमतौर पर प्रदर्शन कारणों से होता है, जो कुछ या अन्य के आलसी मूल्यांकन का समर्थन करता है। –

1

दुर्भाग्य से सी #/vb.net में कोई अपरिवर्तनीय कीवर्ड नहीं है, हालांकि इसकी बहस हुई है, लेकिन यदि कोई ऑटोप्रोपर्टीज नहीं है और सभी फ़ील्ड को केवल पढ़ने के साथ घोषित किया जाता है (केवल पढ़ने वाले फ़ील्ड केवल कन्स्ट्रक्टर में असाइन किए गए शर्त) modfier और यह सब खेतों को एक अपरिवर्तनीय प्रकार की घोषणा की जाती है जिसे आपने अपनी आत्म अपरिवर्तनीयता का आश्वासन दिया होगा।

1

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

एक बिंदु जो अन्य उत्तरों ने उपेक्षित किया है, हालांकि, किसी वस्तु के राज्य की परिभाषा है। यदि Foo एक वर्ग है, तो List<Foo> की स्थिति में ऑब्जेक्ट पहचान का अनुक्रम शामिल है। यदि किसी विशेष List<Foo> इंस्टेंस का एकमात्र संदर्भ कोड द्वारा आयोजित किया जाता है जो न तो उस अनुक्रम को परिवर्तित कर देगा, न ही ऐसा करने के लिए कोड को बेनकाब कर देगा, तो वह उदाहरण अपरिवर्तनीय होगा, भले ही Foo उसमें निर्दिष्ट ऑब्जेक्ट्स हों उत्परिवर्तनीय या अपरिवर्तनीय।

एक समानता का उपयोग करने के लिए, यदि किसी के पास छेड़छाड़ वाले पेपर पर मुद्रित ऑटोमोबाइल वीआईएन (वाहन पहचान संख्या) की एक सूची है, तो कार स्वयं नहीं होने के बावजूद सूची अपरिवर्तनीय होगी।यहां तक ​​कि यदि सूची में आज दस लाल कारें हैं, तो इसमें कल दस नीली कारें हो सकती हैं; हालांकि, वे अभी भी एक ही दस कारें होंगी।

संबंधित मुद्दे