2011-11-02 3 views
36

मैं कक्षा बनाने पर काम कर रहा हूं और अचानक एक विचार मेरे दिमाग में आया कि दोनों कोडों के बीच क्या अंतर है:एक पाठक संशोधक और एक निजी सेटर के बीच कौन सा बेहतर है?

public readonly string ProductLocation; 

और

public string ProductLocation 
{ 
    get; 
    private set; 
} 

क्या आप मुझे विचार दे सकते हैं निम्नलिखित बेहतर उपयोग करने के लिए। धन्यवाद।

उत्तर

51

पहला वाला केवल पढ़ने वाला फ़ील्ड है, जबकि दूसरा एक विधि के रूप में संकलित हो जाता है (और संपत्ति ProductLocation के सभी पढ़ने को संबंधित get विधि पर कॉल में संकलित किया जाता है और लिखता है कि इसे कॉल में संकलित किया जाता है set विधि के लिए; आंतरिक रूप से, ये विधियां एक आंतरिक, स्वचालित रूप से जेनरेट की गई, गैर-पढ़ने-योग्य फ़ील्ड से पढ़ी/लिखेंगी)। मैं कहूंगा कि सबसे महत्वपूर्ण अंतर थ्रेड-सुरक्षा है! (कैसे? पढ़ना!)

कक्षा का मूल उपयोग बिल्कुल देखेंगे: अन्य कक्षाओं में कोड केवल मूल्य को पढ़ने में सक्षम होगा, इसे बदल नहीं पाएगा। साथ ही, मूल्य को पढ़ने के लिए कोड बिल्कुल वही दिखाई देगा (उदाहरण के लिए, print(myInstace.ProductLocation); यहां, आप यह नहीं बता सकते कि इसे कैसे घोषित किया गया है, ठंडा, एह?)

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

अब थ्रेड-सुरक्षा के लिए।readonly फ़ील्ड पर विशेषता कई मेमोरी (जैसे जावा के final फ़ील्ड) के साथ काम कर रहे हैं, तो इसकी मेमोरी दृश्यता अर्थशास्त्र बदल जाएगी।

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

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

तो, अगर कुछ है कि मूल्य शब्दार्थ वस्तु के निर्माण के बाद बदला नहीं जा सकता का प्रतिनिधित्व करता है, तो आप एक निजी सेटर की घोषणा नहीं करना चाहिए (इस अर्थ होगा कि वस्तु इसे बदल सकता है)। केवल पढ़ने के लिए जाएं (और शायद इसे निजी घोषित करें और केवल एक गेटटर के साथ सार्वजनिक संपत्ति घोषित करें! यह वास्तव में पसंदीदा रूप है, क्योंकि खेतों का पर्दाफाश करना अच्छा नहीं है, केवल तरीकों का पर्दाफाश करना बेहतर है - वहां कई कारणों से this answer में इसके कारणों का स्पष्टीकरण) कर रहे हैं

+3

मेरे लिए, सबसे महत्वपूर्ण अंतर अपरिवर्तनीय संपत्ति है क्योंकि वास्तव में कुछ अर्थपूर्ण मूल्यों का पालन करता है। – Freek

6

पहले एक (readonly का प्रयोग करके) मतलब यह होगा कि वस्तु भी एक बार वस्तु instantiated कर दिया गया है, अपने स्वयं के फ़ील्ड का मान संशोधित नहीं कर सकते, और दूसरों को इसे संशोधित नहीं कर सकते।

दूसरा एक (private set का प्रयोग करके) मतलब यह होगा कि वस्तु अपने क्षेत्र का मूल्य संशोधित कर सकते हैं के बाद यह instantiated किया गया है, लेकिन दूसरों को इसे संशोधित नहीं कर सकते।

मैं कुछ है कि आप जानते हैं नहीं बदलेगा के लिए पूर्व का प्रयोग करेंगे, और कुछ जहां बदल सकते हैं के लिए बाद उपयोग करें, लेकिन आप दूसरों इसे बदलने के लिए नहीं करना चाहती।

18

आम तौर पर, इसे सदस्य क्षेत्रों को सार्वजनिक रूप से बेनकाब करने के लिए .NET में प्रोत्साहित नहीं किया जाता है, जिन्हें किसी संपत्ति द्वारा लपेटा जाना चाहिए। तो चलो मान लें आप

private readonly string productLocation; 
public string ProductLocation { get { return productLocation; } } 

बनाम

public string ProductLocation { get; private set; } 

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

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

यदि आप एक अपरिवर्तनीय क्षेत्र के निर्माण के बाद अवधारणा को लागू करना चाहते हैं, तो readonly का उपयोग करें। लेकिन एक डीटीओ के लिए, मैं private set; विकल्प के लिए जा सकता हूं, मुख्य रूप से क्योंकि यह कम बॉयलरप्लेट कोड है।

+2

बस जागरूक रहें कि 'निजी सेट;' विकल्प थ्रेड-सुरक्षित नहीं है। –

+0

रीडोनली फ़ील्ड को लपेटने के लिए वास्तव में दृष्टिकोण की सिफारिश की जाती है? मैं आलसी डेवलपर हूं और यही कारण है कि मैं पूछ रहा हूं। सार्वजनिक रीडोनली स्ट्रिंग उत्पादस्थान निश्चित रूप से छोटा संस्करण है - और इसके कारण यह मेरे लिए बेहतर प्रतीत होता है। – Krzysztof

4

पहला फ़ील्ड जिसका मूल्य केवल तत्काल पर सेट किया जा सकता है।

दूसरा एक संपत्ति जिसका मूल्य (लेकिन केवल अपने युक्त वस्तु से) पर सेट किया जा सकता किसी भी समय है।


सुधार: संपत्ति किसी भी समय किसी भी वर्ग के किसी भी उदाहरण (और न केवल इसकी वस्तु के द्वारा) सेट की जा सकती है।

+2

यह सही नहीं है। संपत्ति किसी भी समय ** किसी भी कक्षा ** के किसी भी उदाहरण द्वारा सेट की जा सकती है (और न केवल * इसके ऑब्जेक्ट * द्वारा)। स्पष्टीकरण के लिए –

+0

+1 ब्रूनो धन्यवाद। –

+0

@ ब्रूनो रीइस, और एक उदाहरण और एक वस्तु के बीच क्या अंतर है? उदाहरण के बिना, आपके पास कोई ऑब्जेक्ट नहीं है। क्या कोई स्पष्टीकरण दे सकता है ?! – usefulBee

7

C# 6.0ऑटो संपत्ति प्रारंभकर्ता साथ

private readonly string productLocation; 
public string ProductLocation { get { return productLocation; } } 

करने का कम बॉयलरप्लेट रास्ता कौन सा है

public string ProductLocation { get; } 

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

हालांकि, यदि आप निजी सेट का उपयोग करते हैं;

public string ProductLocation { get; private set } 

यह बाहर से पढ़ा जाता है। लेकिन किसी भी समय कक्षा के भीतर कहीं भी शुरू किया जा सकता है।और कक्षा के अपने जीवन चक्र के भीतर ही संपादित किया जा सकता है। (वर्ग से उत्परिवर्तनीय, बाहर से अपरिवर्तनीय)

+0

अच्छा अपडेट भाई! धन्यवाद :) –

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