2008-10-06 12 views
12

कक्षा के गुण के भीतर प्राप्त/सेट होने के नए दृष्टिकोण के साथ:सी # 3.0 स्वचालित गुण, फ़ील्ड का उपयोग क्यों न करें?

public string FirstName { 
     get; set; 
    } 

क्यों एक्सेसर के बिना फर्स्टनाम सार्वजनिक रूप से विशेषता नहीं है?

+0

[स्वत: कार्यान्वित गेटर्स और सेटर्स बनाम सार्वजनिक क्षेत्रों] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/111461/auto-implemented-getters-and-setters-vs-public-fields) – nawfal

उत्तर

30

वर्ग (क्षेत्र/विशेषता) के अंदर चर के लिए सीधी पहुँच के साथ बड़ी समस्याओं में से दो हैं:

1) आप आसानी से खेतों के खिलाफ DataBind नहीं कर सकता।

2) आप अपनी कक्षाओं से सार्वजनिक क्षेत्रों आप बाद में (संपत्तियों के लिए उन्हें बदल नहीं सकते, उदाहरण के लिए बेनकाब हैं: setters को मान्यता तर्क जोड़ने के लिए)

+1

(पुनः 2) खेतों और गुणों का उपयोग करते समय समान वाक्यविन्यास नहीं है? –

+2

@damagednoob - कंपाइलर द्वारा उत्पन्न आईएल अलग है, और प्रतिबिंब कोड अलग है क्योंकि गुण और फ़ील्ड अलग हैं। यही कारण है कि इसे एक तोड़ने वाला बदलाव माना जाता है। यदि आप अपने सभी क्लाइंट कोड को पुनः संकलित कर सकते हैं, और आप प्रतिबिंब का उपयोग नहीं करते हैं, तो यह आपके लिए काम कर सकता है। –

+1

मुझे लगता है कि बिंदु 2 बेहद मामूली है जब तक आप .NET ढांचे की तरह कुछ लिखना न हो। लाइब्रेरी को बदलने के लिए यह सामान्य नहीं है और ग्राहकों को एप्लिकेशन के बिना अपडेट किए गए लाइब्रेरी को धक्का देने की उम्मीद है - और यदि आप किसी आंतरिक प्रकार (पहली जगह में सबसे अधिक प्रकार) से निपट रहे हैं तो तर्क एक पूर्ण गैर-स्टार्टर है पहले स्थान पर। –

14

क्योंकि, यदि आप कार्यान्वयन को बदलते हैं, तो वर्तमान इंटरफ़ेस का उपयोग करके कोड तोड़ नहीं जाएगा।

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

किसी संपत्ति का उपयोग करके, आप प्रभावी ढंग से जोखिम को कम कर सकते हैं।

3

यह ज्यादातर के लिए यह एक आम कोडिंग बन रही नीचे आता है सम्मेलन। यदि आप चाहें तो कस्टम प्रोसेसिंग कोड जोड़ना आसान बनाता है। लेकिन आप सही हैं, इसके लिए तकनीकी रूप से कोई वास्तविक आवश्यकता नहीं है। हालांकि, यदि आप बाद में कस्टम प्रसंस्करण जोड़ते हैं, तो यह आपको इंटरफ़ेस को तोड़ने में मदद करेगा।

0

मुझे लगता है कि प्रश्नकर्ता पूछ रहा है क्यों निम्न नहीं ...

public string FirstName { } 

क्यों accessors से परेशान जब आप ऊपर के लिए इसे छोटा कर सकते हैं। मुझे लगता है कि जवाब यह है कि एक्सेसर्स की आवश्यकता से कोड को पढ़ने वाले व्यक्ति को यह स्पष्ट हो जाता है कि यह मानक मानक/सेट है। उनके बिना आप ऊपर देख सकते हैं यह स्पॉट करना मुश्किल है कि इसे स्वचालित रूप से कार्यान्वित किया जा रहा है।

+0

यह "संपत्ति या सूचकांक में कम से कम एक एक्सेसर होना चाहिए" त्रुटि देता है। – BlackWasp

+0

यह संकलक {get; } या {सेट; } या {प्राप्त करें; आंतरिक सेट; } आदि ... गायब एक्सेसर का मतलब है कि कोई एक्सेसर नहीं है। –

1

कुंजी यह है कि कंपाइलर एक फंक्शन जोड़ी में 'हुड के तहत' संपत्ति का अनुवाद करता है, और जब आपके पास ऐसा कोड होता है जो संपत्ति का उपयोग कर रहा है तो यह वास्तव में आईएल को संकलित करते समय कार्यों को कॉल कर रहा है।

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

0

99% मामलों के लिए, सार्वजनिक क्षेत्र का खुलासा ठीक है।

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

  • अपने वर्ग के उपभोक्ताओं को शायद पुन: संयोजित कर सकते हैं जब आप अपने इंटरफेस बदल जाते हैं।

  • आपके डेटा सदस्यों में से 99% को कभी भी गैर-तुच्छ गुणों की आवश्यकता नहीं होगी। यह speculative generality है। आप बहुत सारे कोड लिख रहे हैं जो प्रोबबी कभी उपयोगी नहीं होगा।

  • यदि आपको संस्करणों में बाइनरी संगतता की आवश्यकता है, तो गुणों में डेटा सदस्यों को संभवतः पर्याप्त नहीं है। कम से कम, आपको केवल इंटरफेसिस का पर्दाफाश करना चाहिए और सभी रचनाकारों को छिपाना चाहिए, और कारखानों का पर्दाफाश करना चाहिए (नीचे कोड देखें)।


public class MyClass : IMyClass 
{ 
    public static IMyClass New(...) 
    { 
     return new MyClass(...); 
    } 
} 

यह एक कठिन समस्या है, कोड है कि अनिश्चित भविष्य में काम करेंगे बनाने की कोशिश कर रहा है। वास्तव में मुश्किल है।

Does anyone have an example of a time when using trivial properties saved their bacon?

+0

हम्म, क्या कोई अनुमान लगा सकता है कि मेरा कोड कोड के रूप में क्यों प्रारूपित नहीं है? –

+0

हाँ भविष्य के सबूत कोड बनाना मुश्किल है। इसलिए, आप सार्वजनिक क्षेत्रों के बजाय संपत्तियों का उपयोग करने जैसी सभी सावधानी बरतें। यह इतना आसान है कि यह वास्तव में एक ब्रेनर है। –

+0

@Jay Bazuzi: ऐसा लगता है कि यदि आप बुलेट सूची के बीच में हैं तो कोड स्वरूपण डब्लूएमडी में काम नहीं करता है। यदि आप सूची और कोड के बीच कुछ भी जोड़ते हैं, तो यह सही तरीके से प्रारूपित होगा।मैंने अभी भी बीच में रखने के लिए उपयोगी कुछ भी कम करने के लिए एक क्षैतिज नियम जोड़ा। –

0

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

इस काम को आगे बढ़ाना और एक्सेसर पर ब्रेकपॉइंट चिपकाना विकल्पों की तुलना में बहुत आसान है।

-1

यह ऑब्जेक्ट के encapsulation को संरक्षित करता है और कोड को पढ़ने के लिए और अधिक सरल होने के लिए कम करता है।

2

जब आप गेटर और सेटर के लिए अखंडता को मिलाते हैं तो यह नोटेशन की शैली अधिक उपयोगी होती है। उदाहरण के लिए, आप लिख सकते हैं:

public int Foo { get; private set; } 

तुम भी एक आंतरिक सेटर डाल सकता है, या यहाँ तक गेटर निजी और सेटर सार्वजनिक करें।

यह नोटेशन आंतरिक रूप से लिखने योग्य/बाहरी पठनीय मूल्य की क्लासिक समस्या को संभालने के लिए स्पष्ट रूप से एक निजी चर लिखने की आवश्यकता से बचाता है।

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