2009-11-09 10 views
5

विजुअल स्टूडियो 2008 टीम सिस्टम में, मैंने अपनी सी # परियोजनाओं में से एक पर कोड विश्लेषण (विश्लेषण मेनू से) चलाया। उत्पादित चेतावनी निम्न में से एक था:सी # संरक्षित क्षेत्र निजी, संपत्ति जोड़ें - क्यों?

Microsoft.Design: क्योंकि क्षेत्र 'Connection._domain' अपनी घोषणा के प्रकार के दृश्य के बाहर है, निजी करने के लिए अपनी पहुंच बदल सकते हैं और के रूप में ही पहुँच के साथ एक प्रॉपर्टी जोड़ते हैं, क्षेत्र में वर्तमान में पहुंच प्रदान करने के लिए है।

यह निम्नलिखित क्षेत्र की चर्चा करते हुए है:

public abstract class Connection 
{ 
    protected string _domain; 
} 

मैं सुझाव के पीछे तर्क समझ में नहीं आता।

public abstract class Connection 
{ 
    private string _domain; 
    protected string Domain { get { return _domain; } set { _domain = value; } } 
} 

दो सवाल:: यह यह मुझे क्या करना चाहता है मुझे लगता है कि है

  1. मैं सही ढंग से समझ क्या सुझाव है, मुझे क्या करना चाहता है कोड के लिहाज से?
  2. यह मुझे ऐसा क्यों करना चाहता है?
+0

यह भी देखें http://stackoverflow.com/questions/1410645/are-public-fields-ever-ok, http://stackoverflow.com/questions/480627/why-wont-anyone-accept-public-fields -इन-सी, http://stackoverflow.com/questions/1277572/should-i-use-public-properties-and-private-fields-or-public-fields-for- डेटा और कई और (सार्वजनिक पर खोजें खेत')। वे सभी सार्वजनिक क्षेत्रों पर चर्चा करते हैं लेकिन आम तौर पर संरक्षित क्षेत्रों पर भी लागू होते हैं। –

उत्तर

13

हाँ, मुझे लगता है कि आप सही तरीके से समझ में आ - सी # के बाद के संस्करणों में, वहाँ एक अधिक संक्षिप्त यह लिखने के लिए रास्ता नहीं है, हालांकि:

public string Domain { get; set; } 

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

+0

अपने मामले में, संरक्षित स्ट्रिंग डोमेन {प्राप्त करें; सेट; } ' – nawfal

2

हाँ। यही सुझाव है। प्रत्यक्ष उदाहरण फ़ील्ड के रूप में आपके सामने निजी से अधिक पहुंच नहीं होनी चाहिए।

यह ओओडी के मुख्य सिद्धांतों में से एक है - encapsulation को 'डेटा-छिपाने' के रूप में भी जाना जाता है।

2
  1. हां, आपने समस्या को कोड के अनुसार सही किया है।
  2. यह encapsulation के बारे में है। _domain आपकी ऑब्जेक्ट के बारे में डेटा है। इसके बजाय इसे सीधे उजागर करना ताकि किसी भी ग्राहक के पास पहुंच रहित पहुंच हो, तो आपको इसे एक्सेस करने के लिए एक इंटरफ़ेस प्रदान करना चाहिए। व्यावहारिक रूप से यह सेटटर को सत्यापन जोड़ रहा है ताकि इसे किसी भी मान पर सेट न किया जा सके। यह मूर्खतापूर्ण प्रतीत हो सकता है यदि आप केवल एक ही लेखन कोड हैं क्योंकि आप जानते हैं कि आपका एपीआई कैसे काम करता है। लेकिन बड़े उद्यम स्तर पर चीजों के बारे में सोचने की कोशिश करें, एपीआई रखना बेहतर है ताकि आपकी ऑब्जेक्ट को एक बॉक्स के रूप में देखा जा सके। आप कह सकते हैं कि आपको उस वस्तु के सत्यापन की तरह कुछ जोड़ने की आवश्यकता नहीं होगी, लेकिन इसकी संभावनाओं को पकड़ने के लिए चीजें पूरी तरह से की जाती हैं, और यह भी सुसंगत रहती हैं।
2

ऐसा इसलिए है क्योंकि यदि आप कभी भी भविष्य में किसी संपत्ति में क्षेत्र को बदलना चाहते हैं तो आप उस पर निर्भर किसी अन्य असेंबली को तोड़ देंगे।

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

+0

डाउनवोट क्यों? तकनीकी रूप से यह सच है। एक क्षेत्र तक पहुंचने के लिए आईएल एक प्रोपर्टी तक पहुंचने से अलग है। यदि आप किसी असेंबली (ए) को संकलित करते हैं जो एक अलग असेंबली (बी) में फ़ील्ड का संदर्भ देता है, तो असेंबली (बी) को अपडेट करें और फ़ील्ड्स को गुणों में बदलें, असेंबली (ए) टूटा जाएगा। – Bob

+0

मैं सहमत हूं, बॉब, मुझे लगता है कि यह एक बहुत ही महत्वपूर्ण विचार है। (+1) किसी प्रॉपर्टी में फ़ील्ड बदलना (क्योंकि आप सत्यापन तर्क या लॉगिंग जोड़ना चाहते हैं या इसे वर्चुअल बनाना चाहते हैं, या जो भी अन्य कारण हो सकता है) कक्षा के किसी भी उपयोगकर्ता को बाइनरी ब्रेकिंग चेंज है। यदि आप सम्मेलन के रूप में अपने फ़ील्ड लोअरकेस और गुण अपरकेस का नाम देते हैं तो यह स्रोत स्तर का ब्रेक होने की भी संभावना है। – Joren

+0

और यही वजह है कि आपको गुणों का उपयोग करना चाहिए। यदि यह मामला नहीं था तो तब तक संपत्तियों का उपयोग करने का कोई कारण नहीं होगा जब तक कि आपने तय नहीं किया कि आपको उनकी आवश्यकता है। मैंने सोचा कि सवाल/शग का जवाब दिया :) – GraemeF

2

आपका अनुवाद सही है।'संरक्षित' गुणों का उपयोग करने के लिए उसी तर्क के लिए बनाया जा सकता है जिसे सदस्य चर का खुलासा करने के बजाय 'सार्वजनिक' गुणों का उपयोग करने के लिए बनाया जा सकता है।

यदि यह केवल साधारण गेटर्स और सेटर्स के प्रसार की ओर जाता है तो मुझे लगता है कि कोड रीडब्बिलिटी को नुकसान भविष्य में कोड बदलने में सक्षम होने के लाभ से अधिक है। सी # में संकलक उत्पन्न गुण के विकास के साथ यह काफी इतना बुरा नहीं है, बस का उपयोग करें:

protected string Domain { get; set; } 
0

जवाब में अपने प्रश्न का ... हाँ।

public abstract class Connection 
{ 
    protected string Domain { get; set; } 
} 
0

असल में, संपत्ति को वापस करने या एक सदस्य की स्थापना की तुलना में अधिक प्रदान करते हैं:

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

लिंक से चयनित उत्तर इसे सर्वोत्तम बनाता है, "गुण encapsulation प्रदान करते हैं। आप किसी भी आवश्यक सत्यापन/प्रारूप/रूपांतरण में encapsulate कर सकते हैं संपत्ति के लिए कोड। खेतों के लिए करना मुश्किल होगा। "

http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42

0

यहाँ उल्लेख अन्य उत्तर के अलावा, सार्वजनिक/संरक्षित सदस्यों को बताया कि एक अंडरस्कोर से शुरू नहीं CLS-compliant कि में नेट भाषाओं प्रमुख अंडरस्कोर से सदस्यों का समर्थन करने के लिए कोई आवश्यकता नहीं है वहाँ है, तो किसी को कर रहे हैं, आपकी कक्षा से अलग-अलग .NET भाषा में विरासत प्राप्त करना उस विशेष संरक्षित सदस्य तक पहुंचने में सक्षम नहीं हो सकता है।

मुझे पता है, यह शायद आपके लिए लागू नहीं होता है, लेकिन यह कोड विश्लेषण चेतावनी के कारण का हिस्सा हो सकता है।

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