C # में "आंतरिक" कीवर्ड के लिए व्यावहारिक उपयोग


419

क्या आप बता सकते हैं कि internalC # में कीवर्ड के लिए व्यावहारिक उपयोग क्या है ?

मुझे पता है कि internalसंशोधक वर्तमान विधानसभा तक पहुंच को सीमित करता है, लेकिन मुझे कब और किस परिस्थिति में इसका उपयोग करना चाहिए?

जवाबों:


379

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

से MSDN (archive.org के माध्यम से):

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

आप आंतरिक संशोधक का उपयोग भी कर सकते हैं InternalsVisibleTo "मित्र" असेंबली बनाने के विधानसभा स्तर की विशेषता जिन्हें लक्ष्य विधानसभा आंतरिक कक्षाओं के लिए विशेष पहुंच प्रदान की जाती है।

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


8
InternalsVanishTo विशेषता एक बड़ी मदद है। धन्यवाद।
रोकें

33
मेरी भावना यह है कि जिस क्षण से आपको आंतरिक की आवश्यकता है, कहीं न कहीं कुछ गलत है। IMHO, सभी समस्याओं को हल करने के लिए शुद्ध OO का उपयोग करने में सक्षम होना चाहिए। इस क्षण में, मैं .NET फ्रेमवर्क स्रोत में आंतरिक के एक मिलियन उपयोग के बारे में घूर रहा हूं, वे अपने द्वारा उपयोग किए जाने वाले सामान का लाभ उठाने के लिए अपने रास्ते पर रोक रहे हैं। आंतरिक के उपयोग के माध्यम से, उन्होंने एक मोनोलिथ बनाया जो सतही रूप से मॉड्यूलर है, लेकिन जब आप सामान को अलग करने की कोशिश करते हैं तो टूट जाता है। इसके अलावा, सुरक्षा एक तर्क नहीं है, क्योंकि बचाव के लिए प्रतिबिंब है।
डेसपेयर

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

3
इसे दूसरे तरीके से रखने के लिए, यदि हर कोई SmtpClient के इंटर्नल पर निर्भर होगा, और एक पल में वहाँ एक बग की खोज की गई थी, तो .NET को उस बग को ठीक करने के लिए गंभीर समस्याएं होंगी, शायद इसे लंबे समय तक इधर-उधर रखना भी। मुझे याद है कि मैंने एक मनोरंजक लेख पढ़ा था जिसमें एक बार विंडोज डेवलपर्स को विभिन्न आंतरिक विशेषताओं और बग्स का उपयोग करने वाले सभी पुराने कार्यक्रमों के साथ "बगड्रेस संगतता" रखने के लिए लंबाई तक जाना पड़ा था। .NET के साथ इस त्रुटि को दोहराना सार्थक नहीं है।
केटी।

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

85

अगर Bob को BigImportantClass की आवश्यकता है, तो Bob को उन लोगों को प्राप्त करने की आवश्यकता है जो अपने प्रोजेक्ट A को साइन अप करने के लिए गारंटी देते हैं कि BigImportantClass को उनकी आवश्यकताओं को पूरा करने के लिए लिखा जाएगा, यह सुनिश्चित करने के लिए परीक्षण किया जाएगा कि यह उनकी जरूरतों को पूरा करता है, और उनकी आवश्यकताओं को पूरा करने के रूप में प्रलेखित है। यह सुनिश्चित करने के लिए रखा जाएगा कि इसे कभी नहीं बदला जाएगा ताकि उसकी जरूरतों को पूरा न किया जा सके।

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

आंतरिक की बात यह नहीं है कि यह बॉब के लिए जीवन को कठिन बनाता है। यह है कि यह आपको यह नियंत्रित करने की अनुमति देता है कि प्रोजेक्ट ए सुविधाओं, जीवनकाल, संगतता और इतने पर क्या महंगा वादे करता है।


5
एकदम सही समझ में आता है। बस इच्छा है कि हमारे पास आंतरिक सदस्यों को ओवरराइड करने की क्षमता है, क्योंकि हम सभी वयस्क यहां सहमति दे रहे हैं।
cwallenpoole

6
@ EricLippert काफी मेरा मतलब नहीं था। यदि मुझे संकलित कोड विरासत में मिला है, जिसमें "आंतरिक" है, तो मैं फंस गया हूं, है ना? संकलक को "नो, कि अन्य डेवलपर ने आपसे झूठ बोला था, यह बताने का कोई तरीका नहीं है। आपको तब तक मुझ पर भरोसा करना चाहिए" जब तक कि मैं प्रतिबिंब का उपयोग नहीं करता।
cwallenpoole

11
@cwallenpoole: यदि आप झूठे द्वारा लिखे गए कोड का उपयोग कर रहे हैं, जो कोड आपको पसंद नहीं है, तो उनके कोड का उपयोग करना बंद करें और अपना खुद का कोड लिखें जिसे आप बेहतर पसंद करते हैं।
एरिक लिपर्ट

2
@ EricLippert गाल में जीभ होना चाहिए था, मेरा मतलब अपमान करना नहीं था। (मैं ज्यादातर सिर्फ यह पुष्टि करने की कोशिश कर रहा था कि मैं ऐसे मामलों में एसओएल हूं)।
cwallenpoole

5
@ cwallenpoole: मैं कम से कम नाराज नहीं हूं। मैं अच्छी सलाह दे रहा हूं कि आपको खुद को उस दुर्भाग्यपूर्ण स्थिति में फंसना चाहिए।
एरिक लिपर्ट

60

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


4
Pff। एक disassembler के साथ bytecode को देखकर अभी भी यह स्पष्ट हो जाएगा कि कोड वैसे भी क्या करता है। Obfuscators मुश्किल से किसी को भी वास्तव में आंतरिक में लाने की कोशिश कर रहे एक हल्का बाधा है। एक हैकर के बारे में कभी नहीं सुना जो सिर्फ इसलिए रुक गया क्योंकि उसे कोई उपयोगी फ़ंक्शन नाम नहीं मिला।
Nyerguds

28
इसलिए जब आप सोते हैं तो आप अपने दरवाजे को बंद नहीं करते हैं, क्योंकि आपने कभी किसी चोर को ताला बंद करके नहीं सुना है?
सर्जियो

4
यही कारण है कि मैं स्रोत कोड में वर्ग और चर नामों को हाथापाई करता हूं। आप यह पता लगाने में सक्षम हो सकते हैं कि पम्पस्टैट कॉमपैरेटर क्या है, लेकिन क्या आप अनुमान लगा सकते हैं कि LpWj4mWE क्या है? #jobsecurity (मैं ऐसा नहीं करता, और कृपया वास्तव में ऐसा न करें, इंटरनेट के लोग।)
स्लॉथिरियो

32

यदि आप एक डीएलएल लिख रहे हैं जो एक टन की कार्यक्षमता को सरल सार्वजनिक एपीआई में कूटबद्ध करता है, तो "आंतरिक" का उपयोग कक्षा के सदस्यों पर किया जाता है, जिन्हें सार्वजनिक रूप से उजागर नहीं किया जाना है।

छिपाई जटिलता (उर्फ एनकैप्सुलेशन) गुणवत्ता सॉफ्टवेयर इंजीनियरिंग की मुख्य अवधारणा है।


20

जब आप गैर-प्रबंधित कोड पर एक आवरण बना रहे हों, तब आंतरिक कीवर्ड का भारी उपयोग किया जाता है।

जब आपके पास एक C / C ++ आधारित पुस्तकालय होता है, जिसे आप DllImport करना चाहते हैं, तो आप इन कार्यों को एक वर्ग के स्थिर कार्यों के रूप में आयात कर सकते हैं, और उन्हें आंतरिक बना सकते हैं, इसलिए आपके उपयोगकर्ता के पास केवल आपके रैपर तक पहुँच है और मूल API तक नहीं। किसी भी चीज़ के साथ खिलवाड़। स्टैटिक होने के कारण आप असेंबली में उन सभी रैपर क्लास के लिए इस्तेमाल कर सकते हैं, जिनकी आपको जरूरत है।

आप Mono.Cairo पर एक नज़र डाल सकते हैं, यह कैरो लाइब्रेरी के चारों ओर एक आवरण है जो इस दृष्टिकोण का उपयोग करता है।


12

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

जैसा कि असेंबली इंटरफ़ेस आमतौर पर इसके वर्ग इंटरफेस के योग से अधिक संकीर्ण होता है, ऐसे कई स्थान हैं जहां मैं इसका उपयोग करता हूं।


3
यदि आप "सख्त संशोधक के रूप में उपयोग कर सकते हैं" तो निजी क्यों नहीं?
आर। मार्टिनो फर्नांडिस

6
चूँकि निजी बहुत सख्त है, जब वर्ग के गुणों / विधियों को कक्षा के बाहर पहुँचा जाना चाहिए, और ऐसे मामलों में जब उन्हें दूसरे एस्से से एक्सेस किया जाना चाहिए, बेली अक्सर ऐसा नहीं होता है।
इल्या कोमाखिन

11

मुझे लगता है कि आंतरिक का अत्यधिक उपयोग किया जा रहा है। आप वास्तव में केवल कुछ वर्गों के लिए कुछ कार्यकलापों को उजागर नहीं कर रहे होंगे जो आप अन्य उपभोक्ताओं के लिए नहीं करेंगे।

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

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

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

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


मैं अक्सर डोमेन ऑब्जेक्ट बनाता हूं, जिसके लिए उनके पास ऐसे सदस्य होते हैं जो एक ही असेंबली के भीतर अन्य डोमेन ऑब्जेक्ट के लिए सार्वजनिक होना चाहिए। हालाँकि, ये वही सदस्य क्लाइंट कोड के लिए उपलब्ध नहीं होने चाहिए जो असेंबली के बाहर हैं। इस तरह की स्थितियों के लिए, 'आंतरिक' बहुत उपयुक्त है।
रॉक एंथोनी जॉनसन

8

एक दिलचस्प दिन दूसरे दिन देखा, शायद सप्ताह, एक ब्लॉग पर जिसे मैं याद नहीं कर सकता। मूल रूप से मैं इसका श्रेय नहीं ले सकता, लेकिन मुझे लगा कि इसमें कुछ उपयोगी अनुप्रयोग हो सकते हैं।

कहते हैं कि आप एक सार वर्ग को किसी अन्य विधानसभा द्वारा देखना चाहते थे, लेकिन आप नहीं चाहते कि कोई इसे विरासत में प्राप्त कर सके। सील काम नहीं करेगा क्योंकि यह एक कारण के लिए सार है, उस विधानसभा के अन्य वर्ग इससे विरासत में मिलते हैं। निजी काम नहीं करेगा क्योंकि आप अन्य विधानसभा में कहीं पैरेंट क्लास घोषित करना चाहते हैं।

namepace Base.Assembly
{
  सार्वजनिक सार वर्ग
  {
    आंतरिक सार शून्य SomeMethod ();
  }

  // यह ठीक काम करता है क्योंकि यह एक ही विधानसभा में है।
  पब्लिक क्लास चाइल्डविथिन: माता-पिता
  {
    आंतरिक ओवरराइड शून्य SomeMethod ()
    {
    }
  }
}

नेमस्पेस अन्य
{
  // कबूम, क्योंकि आप एक आंतरिक विधि को ओवरराइड नहीं कर सकते
  पब्लिक क्लास चाइल्डऑटसाइड: पैरेंट
  {
  }

  पब्लिक क्लास टेस्ट 
  { 

    //बस ठीक
    निजी माता-पिता _parent;

    सार्वजनिक परीक्षण ()
    {
      //अब भी अच्छा है
      _परेंट = नया चाइल्डविथिन ();
    }
  }
}

जैसा कि आप देख सकते हैं, यह प्रभावी रूप से किसी को माता-पिता वर्ग का उपयोग करने की अनुमति देता है, जिससे वह विरासत में नहीं पा सकता है।


7

इस उदाहरण में दो फाइलें हैं: असेम्बली 1। एसईसी और असेम्बली 2।सी। पहली फ़ाइल में एक आंतरिक बेस क्लास, BaseClass है। दूसरी फ़ाइल में, बेसक्लास को तत्काल करने का प्रयास एक त्रुटि पैदा करेगा।

// Assembly1.cs
// compile with: /target:library
internal class BaseClass 
{
   public static int intM = 0;
}

// Assembly1_a.cs
// compile with: /reference:Assembly1.dll
class TestAccess 
{
   static void Main()
   {  
      BaseClass myBase = new BaseClass();   // CS0122
   }
}

इस उदाहरण में, उन्हीं फ़ाइलों का उपयोग करें जिनका आपने उदाहरण 1 में उपयोग किया था, और बेसक्लास की पहुंच स्तर को सार्वजनिक में बदल दें । इसके अलावा सदस्य इंटम की पहुंच स्तर को आंतरिक में बदलें । इस स्थिति में, आप क्लास को तुरंत कर सकते हैं, लेकिन आप आंतरिक सदस्य तक नहीं पहुँच सकते।

// Assembly2.cs
// compile with: /target:library
public class BaseClass 
{
   internal static int intM = 0;
}

// Assembly2_a.cs
// compile with: /reference:Assembly1.dll
public class TestAccess 
{
   static void Main() 
   {      
      BaseClass myBase = new BaseClass();   // Ok.
      BaseClass.intM = 444;    // CS0117
   }
}

स्रोत : http://msdn.microsoft.com/en-us/library/7c5ka91b(VS.80).aspx


6

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

उदाहरण के लिए, एक डीएएल में एक ओआरएम हो सकता है, लेकिन वस्तुओं को व्यावसायिक परत के संपर्क में नहीं आना चाहिए, सभी इंटरैक्शन स्थिर विधियों के माध्यम से और आवश्यक पैरामटर्स में पास होना चाहिए।


6

आंतरिक का एक बहुत ही रोचक उपयोग - बेशक आंतरिक सदस्य केवल उस विधानसभा तक सीमित है जिसमें यह घोषित किया गया है - इसमें से कुछ हद तक "मित्र" कार्यक्षमता प्राप्त कर रहा है। एक मित्र सदस्य कुछ ऐसा है जो केवल विधानसभा के बाहर कुछ अन्य विधानसभाओं में दिखाई देता है जिसमें इसकी घोषणा की गई है। C # मित्र के समर्थन में नहीं बनाया गया है, हालांकि CLR करता है।

आप दोस्त सभा की घोषणा करने के लिए InternalsVoubleToAttribute का उपयोग कर सकते हैं , और मित्र विधानसभा के भीतर से सभी संदर्भ आपके विधानसभा के आंतरिक सदस्यों को मित्र विधानसभा के दायरे में सार्वजनिक रूप से व्यवहार करेंगे। इसके साथ एक समस्या यह है कि सभी आंतरिक सदस्य दिखाई देते हैं; आप चुन और चुन नहीं सकते।

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


5

नियम के रूप में अंगूठे के दो प्रकार के सदस्य होते हैं:

  • सार्वजनिक सतह : बाहरी विधानसभा (सार्वजनिक, संरक्षित और आंतरिक संरक्षित) से दिखाई देती है: कॉलर पर भरोसा नहीं किया जाता है, इसलिए पैरामीटर सत्यापन, विधि प्रलेखन, आदि की आवश्यकता होती है।
  • निजी सतह : बाहरी विधानसभा (निजी और आंतरिक, या आंतरिक वर्ग) से दिखाई नहीं देता: कॉलर को आम तौर पर भरोसा किया जाता है, इसलिए पैरामीटर सत्यापन, विधि प्रलेखन, आदि को छोड़ा जा सकता है।

4

शोर में कमी, आपके पुस्तकालय जितना सरल है उतने कम प्रकार को उजागर करते हैं। टेम्पर प्रूफिंग / सुरक्षा एक और है (हालांकि प्रतिबिंब इसके खिलाफ जीत सकता है)।


4

आंतरिक कक्षाएं आपको अपनी विधानसभा के एपीआई को सीमित करने में सक्षम बनाती हैं। यह आपके एपीआई को समझने के लिए सरल बनाने की तरह लाभ है।

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

मुझे क्लास लेवल और असेंबली लेवल पर इनकैप्सुलेशन होना पसंद है। कुछ ऐसे हैं जो इससे सहमत नहीं हैं, लेकिन यह जानना अच्छा है कि कार्यक्षमता उपलब्ध है।


2

मेरे पास एक प्रोजेक्ट है जो डेटा बैक-एंड के लिए LINQ-to-SQL का उपयोग करता है। मेरे दो मुख्य नामस्थान हैं: बिज़ और डेटा। LINQ डेटा मॉडल डेटा में रहता है और "आंतरिक" चिह्नित है; बिज़ नामस्थान में सार्वजनिक वर्ग हैं जो LINQ डेटा कक्षाओं के चारों ओर लिपटे रहते हैं।

तो वहाँ है Data.Client, और Biz.Client; उत्तरार्द्ध डेटा ऑब्जेक्ट के सभी प्रासंगिक गुणों को उजागर करता है, जैसे:

private Data.Client _client;
public int Id { get { return _client.Id; } set { _client.Id = value; } }

बिज़ ऑब्जेक्ट्स में एक निजी कंस्ट्रक्टर होता है (फ़ैक्टरी विधियों के उपयोग के लिए बाध्य करने के लिए), और एक आंतरिक कंस्ट्रक्टर जो इस तरह दिखता है:

internal Client(Data.Client client) {
    this._client = client;
}

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

यह पहली बार है जब मैंने वास्तव में बहुत उपयोग किया internalहै, और यह काफी उपयोगी साबित हो रहा है।


2

ऐसे मामले हैं जब यह वर्गों के सदस्यों को बनाने के लिए समझ में आता है internal। एक उदाहरण यह हो सकता है कि यदि आप यह नियंत्रित करना चाहते हैं कि कक्षाएं कैसे त्वरित हैं; मान लीजिए कि आप वर्ग के उदाहरण बनाने के लिए किसी प्रकार का कारखाना प्रदान करते हैं। आप कंस्ट्रक्टर बना सकते हैंinternal , ताकि फैक्ट्री (जो एक ही असेंबली में रहती है) क्लास के उदाहरण बना सकते हैं, लेकिन उस असेंबली के बाहर कोड नहीं हो सकता।

हालाँकि, मैं internalविशिष्ट कारणों के बिना कक्षाओं या सदस्यों को बनाने के साथ कोई भी बिंदु नहीं देख सकता , बस उतना ही कम है जितना उन्हें बनाने के लिए publicया privateविशिष्ट कारणों के बिना समझ में आता है ।


1

केवल एक चीज जो मैंने कभी आंतरिक कीवर्ड का उपयोग किया है, वह है मेरे उत्पाद में लाइसेंस-चेकिंग कोड ;-)


1

आंतरिक कीवर्ड का एक उपयोग आपके विधानसभा के उपयोगकर्ता से ठोस कार्यान्वयन तक पहुंच को सीमित करना है।

यदि आपके पास कोई निर्माण करने के लिए कोई कारखाना या कोई अन्य केंद्रीय स्थान है, तो आपके विधानसभा के उपयोगकर्ता को केवल सार्वजनिक इंटरफ़ेस या सार आधार वर्ग से निपटने की आवश्यकता है।

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


1

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

इस दृष्टिकोण के बारे में टिप्पणियों का स्वागत है।


@Samik - क्या आप कृपया विस्तार से बता सकते हैं, "आमतौर पर यह अनुशंसा की जाती है कि आप किसी विधानसभा के बाहरी उपयोगकर्ताओं के लिए सूची ऑब्जेक्ट को उजागर नहीं करते हैं, बल्कि एक IEnumerable को उजागर करते हैं।" क्यों ienumerable पसंद किया जाता है?
होवीकैंप

1
@Howiecamp: अधिकतर क्योंकि IEnumerable सूची को केवल पढ़ने के लिए एक्सेस देता है, जैसे कि यदि आप सीधे सूची को उजागर करते हैं, तो इसे क्लाइंट (जैसे डिलीट एलिमेंट्स आदि) द्वारा संशोधित किया जा सकता है, जो अनपेक्षित हो सकता है।
सामिक आर

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

1

ध्यान रखें कि किसी भी वर्ग के रूप में परिभाषित publicस्वचालित रूप से इंटेलीजेंस में दिखाई देगा जब कोई आपके प्रोजेक्ट नामस्थान को देखता है। एपीआई के नजरिए से, आपके प्रोजेक्ट के उपयोगकर्ताओं को केवल उन कक्षाओं को दिखाना जरूरी है, जिनका वे उपयोग कर सकते हैं। उपयोगinternal चीज़ों को छिपाने के कीवर्ड का जिन्हें उन्हें नहीं देखना चाहिए।

यदि आपका Big_Important_Classप्रोजेक्ट ए के लिए आपकी परियोजना के बाहर उपयोग करने का इरादा है, तो आपको इसे चिह्नित नहीं करना चाहिएinternal

हालाँकि, कई परियोजनाओं में, आपके पास अक्सर ऐसी कक्षाएं होंगी जो वास्तव में केवल एक परियोजना के अंदर उपयोग के लिए होती हैं। उदाहरण के लिए, आपके पास एक वर्ग हो सकता है जो एक पैरामीटर थ्रेड आह्वान के लिए तर्क रखता है। इन मामलों में, आपको उन्हें ऐसे चिह्नित करना चाहिए जैसे internalकि बिना किसी अन्य कारण के बिना किसी अनचाहे एपीआई से खुद को बचाने के लिए सड़क को बदल दें।


तो बजाय निजी उपयोग क्यों नहीं?
कैदी जीरो

1
privateकीवर्ड केवल कक्षाओं या structs कि एक और वर्ग या struct के भीतर परिभाषित कर रहे हैं पर इस्तेमाल किया जा सकता है। एक नाम स्थान के भीतर परिभाषित एक वर्ग केवल घोषित किया जा सकता है publicया internal
मैट डेविस

1

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

  1. भविष्य के रिलीज़ में परिवर्तन की संभावना है (यदि वे सार्वजनिक थे तो आप ग्राहक कोड तोड़ देंगे)
  2. ग्राहक के लिए बेकार हैं और भ्रम पैदा कर सकते हैं
  3. सुरक्षित नहीं हैं (इसलिए अनुचित उपयोग आपके पुस्तकालय को बुरी तरह से तोड़ सकता है)

आदि।

यदि आप आंतरिक तत्वों का उपयोग करने की तुलना में इनडोर समाधान विकसित कर रहे हैं, तो यह महत्वपूर्ण नहीं है कि मुझे लगता है, क्योंकि आमतौर पर ग्राहकों का आपके साथ निरंतर संपर्क और / या कोड तक पहुंच होगी। वे हालांकि पुस्तकालय डेवलपर्स के लिए काफी महत्वपूर्ण हैं।


-7

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

public class DangerousClass {
    public void SafeMethod() { }
    internal void UpdateGlobalStateInSomeBizarreWay() { }
}

तुम क्या कहना चाहते हो? यह बहुत स्पष्ट नहीं है। कम से कम मुझे तो नहीं।
12

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.