2008-09-20 7 views
40

मैं एक सुंदर नया सी # और नेट डेवलपर हूं। मैंने हाल ही में सी # का उपयोग करके एक एमएमसी स्नैपिन बनाया है और यह स्वीकार किया गया था कि यह कितना आसान था, विशेष रूप से मेरे संगठन के कुछ अन्य डेवलपर्स द्वारा बहुत सी डरावनी कहानियों को सुनने के बाद सी ++ में करना कितना मुश्किल है।क्या मुझे डिफ़ॉल्ट रूप से आंतरिक या सार्वजनिक दृश्यता का उपयोग करना चाहिए?

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

उत्तर

35

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

इसके लिए, मुझे केवल उस कार्यक्षमता दें जो कक्षा को काम करने के लिए उजागर करने की आवश्यकता है।

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

+0

एक महान सादृश्य के लिए +1। –

+0

इसके बगल में, इसे सक्रिय करने से पहले सक्रिय नहीं किया गया है ;-) – izbrannick

0

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

1

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

0

उस "डिफ़ॉल्ट" को चुनें जो उस विशेष वर्ग के लिए दृश्यता आवश्यकताओं को सबसे अच्छी तरह से फिट करता है।

class Class1 
{ 
} 

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

+0

आप किन परिस्थितियों में आंतरिक, सार्वजनिक या निजी चुनेंगे? आपको चुनने के लिए कौन सी विशेष ज़रूरतें प्रभावित हो सकती हैं? –

+0

गैर-नेस्टेड कक्षाओं के लिए आंतरिक और निजी समान हैं, जहां तक ​​मुझे पता है: दोनों केवल संपूर्ण असेंबली के लिए दृश्यमान हैं। (या InternalsVisibleTo विशेषता का उपयोग करते समय यह कोई फर्क पड़ता है?) – Tobi

+5

"शीर्ष-स्तरीय प्रकार, जो अन्य प्रकारों में घोंसला नहीं हैं, केवल आंतरिक या सार्वजनिक पहुंच हो सकते हैं। इन प्रकारों के लिए डिफ़ॉल्ट पहुंच आंतरिक है।" (http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx) – Auron

0

मुझे जितनी छोटी हो सके चीजों का पर्दाफाश करना पसंद है। निजी, संरक्षित, आंतरिक, सार्वजनिक: कक्षाएं, चर, गुण, और कार्यों को कम से कम दृश्यता की आवश्यकता होती है जो उन्हें अभी भी काम करने के लिए आवश्यक है।

मैं उस चीज को केवल उस चीज पर टक्कर लूंगा जब उसमें कोई अच्छा कारण न हो।

4

मैं कक्षाओं को public के रूप में चिह्नित करने से बचना पसंद करता हूं जब तक कि मैं स्पष्ट रूप से अपने ग्राहक को उनका उपभोग नहीं करना चाहता, और मैं उनका समर्थन करने के लिए तैयार हूं।

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

7

मुझे लगता है कि आपको आंतरिक कक्षाओं और सदस्यों के पक्ष में गलती करनी चाहिए। आप हमेशा किसी आइटम की दृश्यता बढ़ा सकते हैं लेकिन इससे कम होने से समस्याएं पैदा हो सकती हैं। यह विशेष रूप से सच है यदि आप दूसरों के लिए एक ढांचा बना रहे हैं।

आपको सावधान रहना होगा हालांकि आपके उपयोगकर्ताओं से उपयोगी कार्यक्षमता छिपाने के लिए नहीं। .NET BCL में कई उपयोगी विधियां हैं जिन्हें प्रतिबिंब का उपयोग किए बिना उपयोग नहीं किया जा सकता है।हालांकि इन तरीकों को छिपाने से सतह का क्षेत्र परीक्षण और रखरखाव किया जाना चाहिए।

1

तो ऐसा कोई कारण आप निजी के बजाय आंतरिक उपयोग करने की आवश्यकता है? आपको एहसास है कि आंतरिक में असेंबली स्तर का दायरा है। दूसरे शब्दों में आंतरिक वर्ग/सदस्य बहु-वर्ग असेंबली में सभी वर्गों के लिए सुलभ हैं।

के रूप में कुछ अन्य उत्तर कहा है, सामान्य रूप में संभव के रूप में कैप्सूलीकरण के उच्चतम स्तर के लिए जाना (यानी निजी) जब तक आप वास्तव में आंतरिक/संरक्षित/सार्वजनिक की जरूरत है।

11

आपने जो किया वह ठीक है जो आपको करना चाहिए; अपने वर्गों को सबसे कम दृश्यता दें जो आप कर सकते हैं। ओह, अगर तुम सच में पूरे हॉग जाना चाहते हैं, आप कर सकते हैं सब कुछinternal (अधिकतम) और InternalsVisibleTo attribute का उपयोग करें, ताकि आप अपनी कार्यक्षमता को अलग कर सकते हैं, लेकिन अभी भी अज्ञात बाहर की दुनिया से यह खुलासा नहीं।

चीजों को सार्वजनिक करने का एकमात्र कारण यह है कि आप अपने प्रोजेक्ट को कई डीएलएल और/या EXEs में पैकेजिंग कर रहे हैं और (किसी भी कारण से) आप InternalsVisibleTo का उपयोग करने की परवाह नहीं करते हैं, या आप उपयोग के लिए लाइब्रेरी बना रहे हैं तीसरे पक्ष द्वारा। लेकिन तीसरे पक्ष द्वारा उपयोग के लिए पुस्तकालय में भी, आपको जहां भी संभव हो "सतह क्षेत्र" को कम करने की कोशिश करनी चाहिए; आपके पास जितनी अधिक कक्षाएं उपलब्ध हैं, उतनी ही भ्रमित आपकी लाइब्रेरी होगी।

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

1

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

+1

यह गलत है। आपके पास आंतरिक वर्ग पर सार्वजनिक विधियां और गुण हो सकते हैं, वास्तव में ऐसा करना कई लोगों द्वारा अनुशंसित किया जाता है। – kjbartel

1

आपको उन्हें जितना संभव हो उतना दिखाना चाहिए, लेकिन ऊपर माइक द्वारा बताए गए अनुसार, यह UserControls के साथ समस्याएं उत्पन्न करता है और वीएस डिजाइनर का उपयोग करता है वे फॉर्म या अन्य UserControls पर नियंत्रण।

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

मुझे हाल ही में एक समस्या थी जहां डिजाइनर InitializeComponent() विधि से this.myControl = new MyControl() लाइन को हटा रहा था क्योंकि UserControl MyControl को इसके कन्स्ट्रक्टर के साथ आंतरिक के रूप में चिह्नित किया गया था।

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

0

मैं पूरी तरह से अब तक जवाब के साथ सहमत नहीं हैं। मुझे लगता है कि आंतरिक एक भयानक विचार है, किसी अन्य असेंबली को आपके प्रकारों को विरासत में रखने से रोकता है, या यहां तक ​​कि अपने आंतरिक प्रकारों का उपयोग करने के लिए कामकाज की आवश्यकता होनी चाहिए।

आज, मुझे सिस्टम के आंतरिक भाग प्राप्त करने के लिए प्रतिबिंब का उपयोग करना पड़ा। डेटा। डेटाटाबल (मुझे अपने सभी चेक के बिना एक डाटाटेबल बिजली का निर्माण करना होगा), और मुझे प्रतिबिंब का उपयोग करना पड़ा, मेरे लिए एक भी प्रकार उपलब्ध नहीं था; वे सभी आंतरिक के रूप में चिह्नित थे।

+1

'आंतरिक' मौजूद है ताकि एपीआई विक्रेता (जैसे एमएस) अपने कोड का उपयोग करके यादृच्छिक अजनबियों के बारे में चिंता किए बिना कक्षाएं लिख सकें। जब भी कोई एपीआई सार्वजनिक हो जाता है, विक्रेता अब हस्ताक्षर को आसानी से बदल नहीं सकता है। जब 'आंतरिक', यदि एमएस चुनता है, तो वे अन्य लोगों के कोड को तोड़ने के डर के बिना अपना कोड बदल सकते हैं। यही है, जब तक वे "धोखा" के प्रतिबिंब का उपयोग नहीं कर रहे हैं। –

+0

मेरा तर्क है कि आप निजी और संरक्षित सदस्यों के साथ ऐसा ही कर सकते हैं ताकि कम से कम जब (और मैं कहूं कि "कब", नहीं "अगर") कोई व्यक्ति डाइव करता है, तो वे प्रतिबिंब के बजाय मजबूत टाइपिंग का उपयोग कर सकते हैं। –

+1

@ पेडर, 'निजी' का उपयोग करने से प्रतिबिंब के बजाय मजबूत टाइपिंग का उपयोग करना आसान हो जाता है? 'निजी' '** आंतरिक 'की तुलना में ** कम ** पहुंच योग्य है। और यदि आप 'संरक्षित' का उपयोग करते हैं तो यह अब एपीआई के ** अनुबंध ** का हिस्सा है और एमएस इसे बदलने से प्रतिबंधित होगा। मुझे लगता है कि मैंने उस बिंदु को अनदेखा किया है। –

2

अधिकांश कक्षाएं internal होनी चाहिए, लेकिन अधिकांश गैर-निजी सदस्य public होना चाहिए।

प्रश्न के बारे में आपको क्या सवाल पूछना चाहिए "अगर कक्षा public बनती है तो क्या मैं सदस्य का खुलासा करना चाहता हूं?"। जवाब आमतौर पर "हां (तो public)" है क्योंकि किसी भी सुलभ सदस्यों के बिना वर्गों का अधिक उपयोग नहीं होता है! internal सदस्यों की भूमिका है; वे 'बैक-दरवाजा पहुंच' हैं, केवल एक ही असेंबली में रहने वाले करीबी रिश्तेदारों के लिए।

भले ही आपकी कक्षा आंतरिक रहती है, फिर भी यह देखना अच्छा लगता है कि सामने के दरवाजे के सदस्य कौन हैं और जो पीछे के दरवाजे हैं। और यदि आपने कभी इसे सार्वजनिक रूप से बदल दिया है तो आपको वापस जाना होगा और इस बारे में सोचना होगा कि कौन सा है।

0

डिफ़ॉल्ट वर्ग द्वारा सी #: आंतरिक माध्यमों में आंतरिक के रूप में बनाया गया है: एक्सेस वर्तमान असेंबली तक ही सीमित है।

देख http://msdn.microsoft.com/en-us/library/0b0thckt.aspx

अच्छा अनुच्छेद चूक गुंजाइश आंतरिक है: http://www.c-sharpcorner.com/UploadFile/84c85b/default-scope-of-a-C-Sharp-class/

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

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