2008-12-28 10 views
8

मेरे पास एक संदर्भ-प्रकार चर है जो readonly है, क्योंकि संदर्भ कभी भी नहीं बदलता है, केवल इसकी गुणता है। जब मैंने volatile संशोधक को जोड़ने की कोशिश की तो संकलित ने मुझे चेतावनी दी कि यह दोनों संशोधक एक ही चर पर लागू नहीं होने देगा। लेकिन मुझे लगता है कि मुझे अस्थिर होने की आवश्यकता है क्योंकि मैं अपनी संपत्तियों को पढ़ने के दौरान कैशिंग समस्याओं को नहीं लेना चाहता हूं। क्या मुझे कुछ याद आ रही है? या संकलक गलत है?क्यों रीडोनली और अस्थिर संशोधक पारस्परिक रूप से अनन्य हैं?

अद्यतन मार्टिन के रूप में नीचे टिप्पणी में से एक में कहा गया है: दोनों केवल पढ़ने के लिए और अस्थिर संशोधक संदर्भ प्रकार की वस्तुओं के मामले में केवल संदर्भ के लिए लागू होते हैं, और ऑब्जेक्ट के गुणों के लिए नहीं,। यही वह था जो मैं याद कर रहा था, इसलिए संकलक सही है।

class C 
{ 
    readonly volatile string s; // error CS0678: 'C.s': a field cannot be both volatile and readonly 
} 
+0

कंपाइलर [संभावित रूप से गलत] है (http://stackoverflow.com/q/39004125/1149773) (हालांकि संभवतः आपके विशेष परिदृश्य के लिए नहीं)। – Douglas

उत्तर

14

न तो readonly और न ही volatile संशोधक penetrative हैं। वे संदर्भ पर लागू होते हैं, न कि वस्तु के गुणों पर।

readonly कीवर्ड आवेषण-और लागू करता है- परिवर्तनीय प्रारंभ करने के बाद बदल नहीं सकता है। परिवर्तनीय स्मृति का छोटा हिस्सा है जहां संदर्भ संग्रहीत किया जाता है।

volatile कीवर्ड संकलक को बताता है कि एक चर की सामग्री को कई धागे से बदला जा सकता है। यह संकलक को ऑप्टिमाइज़ेशन का उपयोग करने से रोकता है (जैसे परिवर्तक के मान को एक रजिस्टर में पढ़ना और उस मान का उपयोग कई निर्देशों पर करना) जो समवर्ती पहुंच के साथ समस्याएं पैदा कर सकता है। फिर, यह केवल स्मृति के छोटे हिस्से को प्रभावित करता है जहां संदर्भ संग्रहीत किया जाता है।

इस तरह से लागू, आप देख सकते हैं कि वे वास्तव में परस्पर अनन्य हैं। अगर कुछ पढ़ा जाता है (केवल प्रारंभिक या निर्माण पर, केवल एक बार लिखा जा सकता है), तो यह अस्थिर भी नहीं हो सकता है (किसी भी समय एकाधिक धागे से लिखा जा सकता है)।


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

+1

गुण असुरक्षित हो सकते हैं (मुझे नहीं पता), लेकिन बैकिंग फ़ील्ड निश्चित रूप से हैं। खेतों को अस्थिर चिह्नित किया जाना चाहिए। – configurator

+0

यह उत्तर ओपी के प्रश्न को सही तरीके से संबोधित करता है, लेकिन इसमें एक भ्रामक कथन शामिल है: "अस्थिर कीवर्ड संकलक को बताता है कि एक चर की सामग्री को कई धागे से बदला जा सकता है।" यह केवल आंशिक रूप से सही है; अस्थिर कीवर्ड संकलक को यह भी बताता है कि एक चर की सामग्री को बदला जा सकता है * या कई धागे द्वारा * पढ़ा जा सकता है, भले ही परिवर्तन केवल एक बार किया जाता है। मैंने यहां एक समान प्रश्न उठाया है जो इस मुद्दे को शामिल करता है: [सी # भाषा दोष: अस्थिर और पठनीय रूप से पारस्परिक रूप से अनन्य नहीं होना चाहिए] (http://stackoverflow.com/q/39004125/1149773)। – Douglas

+0

मुझे नहीं लगता कि मेरा बयान भ्रामक है। शायद यह कहना अधिक सटीक होगा कि यह संकलक को बताता है कि थ्रेड इसे पढ़ते समय एक चर के मूल्य को अन्य धागे से बदला जा सकता है, लेकिन मुझे लगता है कि * * वाक्यांश आगे के स्पष्टीकरण के बिना अधिक भ्रामक है, क्योंकि यह संकेत दे सकता है थ्रेड सिंक्रनाइज़ेशन प्रदान करने के लिए 'अस्थिर' सब कुछ आवश्यक है। मुझे लगता है कि मेरा शब्द स्पष्ट रूप से अवधारणा को स्पष्ट करता है, और अगली वाक्य बुनियादी समझ के लिए पर्याप्त जानकारी प्रदान करती है। आपकी समस्या .NET के प्रारंभिक व्यवहार की एक दिलचस्प परीक्षा है, लेकिन इससे इससे कोई फर्क नहीं पड़ता है। –

1

एक केवल पढ़ने योग्य फ़ील्ड केवल ऑब्जेक्ट का निर्माण होने पर ही लिखा जा सकता है। इसलिए सीपीयू पर कोई कैशिंग समस्या नहीं होगी क्योंकि क्षेत्र अपरिवर्तनीय है और संभवतः बदल नहीं सकता है।

+0

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

+2

@ चेतावनी: केवल पढ़ने योग्य और अस्थिर संशोधक केवल संदर्भ (या बूल, int जैसे परमाणु मूल्यों के मामले में मूल्य) की रक्षा करते हैं, वस्तु की सामग्री नहीं! यह एक पूरी तरह से अलग मामला है। –

0

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

+0

लेकिन यह कुछ न तो केवल पढ़ने के लिए और न ही अस्थिर है जिसका बचाव करने के लिए किया गया है। ऐसा कुछ है जिसे आपको सिंक्रनाइज़ेशन के साथ हल करने की आवश्यकता है। –

+0

@ चार्ली, आप कह रहे हैं कि यदि वस्तु अस्थिर है, तो यह गारंटी नहीं देता है कि इसकी संपत्ति अस्थिर हो जाएगी? –

+0

@ मार्टिन सी, बहुत सच है। @ वर्निच, जैसा कि मैं समझता हूं, हां। आपको यह गारंटी देने की आवश्यकता होगी कि आपके फ़ील्ड और गुण थ्रेड-सुरक्षित हैं। –

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

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