क्या आप बता सकते हैं कि internal
C # में कीवर्ड के लिए व्यावहारिक उपयोग क्या है ?
मुझे पता है कि internal
संशोधक वर्तमान विधानसभा तक पहुंच को सीमित करता है, लेकिन मुझे कब और किस परिस्थिति में इसका उपयोग करना चाहिए?
क्या आप बता सकते हैं कि internal
C # में कीवर्ड के लिए व्यावहारिक उपयोग क्या है ?
मुझे पता है कि internal
संशोधक वर्तमान विधानसभा तक पहुंच को सीमित करता है, लेकिन मुझे कब और किस परिस्थिति में इसका उपयोग करना चाहिए?
जवाबों:
उपयोगिता या सहायक कक्षाएं / विधियाँ जिन्हें आप एक ही असेंबली के भीतर कई अन्य वर्गों से एक्सेस करना चाहते हैं, लेकिन यह सुनिश्चित करना चाहते हैं कि अन्य विधानसभाओं में कोड सुनिश्चित नहीं हो पाएं।
से MSDN (archive.org के माध्यम से):
आंतरिक पहुंच का एक सामान्य उपयोग घटक-आधारित विकास में है क्योंकि यह घटकों के एक समूह को एक निजी तरीके से सहयोग करने में सक्षम बनाता है, बाकी एप्लिकेशन कोड के संपर्क में आए बिना। उदाहरण के लिए, ग्राफिकल यूजर इंटरफेस बनाने का एक ढांचा नियंत्रण और प्रपत्र कक्षाएं प्रदान कर सकता है जो आंतरिक पहुंच वाले सदस्यों का उपयोग करने में सहयोग करते हैं। चूंकि ये सदस्य आंतरिक हैं, इसलिए वे उस कोड के संपर्क में नहीं हैं जो फ्रेमवर्क का उपयोग कर रहा है।
आप आंतरिक संशोधक का उपयोग भी कर सकते हैं InternalsVisibleTo
"मित्र" असेंबली बनाने के विधानसभा स्तर की विशेषता जिन्हें लक्ष्य विधानसभा आंतरिक कक्षाओं के लिए विशेष पहुंच प्रदान की जाती है।
यह इकाई परीक्षण विधानसभाओं के निर्माण के लिए उपयोगी हो सकता है जिन्हें तब विधानसभा के आंतरिक सदस्यों को परीक्षण करने की अनुमति दी जाती है। बेशक किसी अन्य विधानसभाओं को इस स्तर तक पहुंच की अनुमति नहीं है, इसलिए जब आप अपना सिस्टम जारी करते हैं, तो एनकैप्सुलेशन बनाए रखा जाता है।
अगर Bob को BigImportantClass की आवश्यकता है, तो Bob को उन लोगों को प्राप्त करने की आवश्यकता है जो अपने प्रोजेक्ट A को साइन अप करने के लिए गारंटी देते हैं कि BigImportantClass को उनकी आवश्यकताओं को पूरा करने के लिए लिखा जाएगा, यह सुनिश्चित करने के लिए परीक्षण किया जाएगा कि यह उनकी जरूरतों को पूरा करता है, और उनकी आवश्यकताओं को पूरा करने के रूप में प्रलेखित है। यह सुनिश्चित करने के लिए रखा जाएगा कि इसे कभी नहीं बदला जाएगा ताकि उसकी जरूरतों को पूरा न किया जा सके।
यदि कोई वर्ग आंतरिक है, तो उसे उस प्रक्रिया से गुजरना नहीं पड़ता है, जो प्रोजेक्ट ए के लिए बजट बचाता है कि वे अन्य चीजों पर खर्च कर सकते हैं।
आंतरिक की बात यह नहीं है कि यह बॉब के लिए जीवन को कठिन बनाता है। यह है कि यह आपको यह नियंत्रित करने की अनुमति देता है कि प्रोजेक्ट ए सुविधाओं, जीवनकाल, संगतता और इतने पर क्या महंगा वादे करता है।
आंतरिक उपयोग करने का एक अन्य कारण यह है कि यदि आप अपने बायनेरिज़ को बाधित करते हैं। पर्यवेक्षक को पता है कि किसी भी आंतरिक वर्गों के वर्ग के नाम को खंगालना सुरक्षित है, जबकि सार्वजनिक वर्गों के नाम को नहीं हटाया जा सकता है, क्योंकि यह मौजूदा संदर्भों को तोड़ सकता है।
यदि आप एक डीएलएल लिख रहे हैं जो एक टन की कार्यक्षमता को सरल सार्वजनिक एपीआई में कूटबद्ध करता है, तो "आंतरिक" का उपयोग कक्षा के सदस्यों पर किया जाता है, जिन्हें सार्वजनिक रूप से उजागर नहीं किया जाना है।
छिपाई जटिलता (उर्फ एनकैप्सुलेशन) गुणवत्ता सॉफ्टवेयर इंजीनियरिंग की मुख्य अवधारणा है।
जब आप गैर-प्रबंधित कोड पर एक आवरण बना रहे हों, तब आंतरिक कीवर्ड का भारी उपयोग किया जाता है।
जब आपके पास एक C / C ++ आधारित पुस्तकालय होता है, जिसे आप DllImport करना चाहते हैं, तो आप इन कार्यों को एक वर्ग के स्थिर कार्यों के रूप में आयात कर सकते हैं, और उन्हें आंतरिक बना सकते हैं, इसलिए आपके उपयोगकर्ता के पास केवल आपके रैपर तक पहुँच है और मूल API तक नहीं। किसी भी चीज़ के साथ खिलवाड़। स्टैटिक होने के कारण आप असेंबली में उन सभी रैपर क्लास के लिए इस्तेमाल कर सकते हैं, जिनकी आपको जरूरत है।
आप Mono.Cairo पर एक नज़र डाल सकते हैं, यह कैरो लाइब्रेरी के चारों ओर एक आवरण है जो इस दृष्टिकोण का उपयोग करता है।
नियम के अनुसार "सख्त संशोधक के रूप में उपयोग करें" द्वारा संचालित होने के कारण, मैं हर जगह आंतरिक उपयोग कर सकता हूं, मुझे किसी अन्य वर्ग से विधि तक पहुंचने की आवश्यकता है, जब तक मुझे स्पष्ट रूप से किसी अन्य विधानसभा से इसे एक्सेस करने की आवश्यकता नहीं है।
जैसा कि असेंबली इंटरफ़ेस आमतौर पर इसके वर्ग इंटरफेस के योग से अधिक संकीर्ण होता है, ऐसे कई स्थान हैं जहां मैं इसका उपयोग करता हूं।
मुझे लगता है कि आंतरिक का अत्यधिक उपयोग किया जा रहा है। आप वास्तव में केवल कुछ वर्गों के लिए कुछ कार्यकलापों को उजागर नहीं कर रहे होंगे जो आप अन्य उपभोक्ताओं के लिए नहीं करेंगे।
यह मेरी राय में इंटरफ़ेस को तोड़ता है, अमूर्तता को तोड़ता है। यह कहना नहीं है कि इसका उपयोग कभी नहीं किया जाना चाहिए, लेकिन एक बेहतर समाधान एक अलग वर्ग के लिए रिफ्लेक्टर है या यदि संभव हो तो एक अलग तरीके से उपयोग किया जाए। हालांकि, यह हमेशा संभव नहीं हो सकता है।
जिन कारणों से यह समस्या हो सकती है, वह यह है कि दूसरे डेवलपर पर उसी विधानसभा में एक अन्य वर्ग बनाने का आरोप लगाया जा सकता है जो आपका है। आंतरिक होने से अमूर्तता की स्पष्टता कम हो जाती है, और दुरुपयोग होने पर समस्याएं पैदा हो सकती हैं। यह वैसा ही मुद्दा होगा जैसा आपने इसे सार्वजनिक किया है। अन्य डेवलपर द्वारा बनाए जा रहे अन्य वर्ग अभी भी किसी भी बाहरी वर्ग की तरह एक उपभोक्ता हैं। क्लास एब्स्ट्रेक्शन और इनकैप्सुलेशन केवल बाहरी वर्गों से / के लिए सुरक्षा के लिए नहीं है, लेकिन किसी भी और सभी वर्गों के लिए।
एक और समस्या यह है कि बहुत सारे डेवलपर्स सोचेंगे उन्हें विधानसभा में कहीं और इसका उपयोग करने की आवश्यकता हो सकती है और इसे आंतरिक रास्ते के रूप में चिह्नित कर सकते हैं, भले ही उन्हें उस समय इसकी आवश्यकता न हो। एक और डेवलपर तब इसे लेने के लिए सोच सकता है। आमतौर पर आप निजी को तब तक चिन्हित करना चाहते हैं जब तक कि आपकी कोई निश्चित आवश्यकता न हो।
लेकिन इसमें से कुछ व्यक्तिपरक हो सकते हैं, और मैं यह नहीं कह रहा हूं कि इसका उपयोग कभी नहीं किया जाना चाहिए। जरूरत पड़ने पर ही इस्तेमाल करें।
एक दिलचस्प दिन दूसरे दिन देखा, शायद सप्ताह, एक ब्लॉग पर जिसे मैं याद नहीं कर सकता। मूल रूप से मैं इसका श्रेय नहीं ले सकता, लेकिन मुझे लगा कि इसमें कुछ उपयोगी अनुप्रयोग हो सकते हैं।
कहते हैं कि आप एक सार वर्ग को किसी अन्य विधानसभा द्वारा देखना चाहते थे, लेकिन आप नहीं चाहते कि कोई इसे विरासत में प्राप्त कर सके। सील काम नहीं करेगा क्योंकि यह एक कारण के लिए सार है, उस विधानसभा के अन्य वर्ग इससे विरासत में मिलते हैं। निजी काम नहीं करेगा क्योंकि आप अन्य विधानसभा में कहीं पैरेंट क्लास घोषित करना चाहते हैं।
namepace Base.Assembly { सार्वजनिक सार वर्ग { आंतरिक सार शून्य SomeMethod (); } // यह ठीक काम करता है क्योंकि यह एक ही विधानसभा में है। पब्लिक क्लास चाइल्डविथिन: माता-पिता { आंतरिक ओवरराइड शून्य SomeMethod () { } } } नेमस्पेस अन्य { // कबूम, क्योंकि आप एक आंतरिक विधि को ओवरराइड नहीं कर सकते पब्लिक क्लास चाइल्डऑटसाइड: पैरेंट { } पब्लिक क्लास टेस्ट { //बस ठीक निजी माता-पिता _parent; सार्वजनिक परीक्षण () { //अब भी अच्छा है _परेंट = नया चाइल्डविथिन (); } } }
जैसा कि आप देख सकते हैं, यह प्रभावी रूप से किसी को माता-पिता वर्ग का उपयोग करने की अनुमति देता है, जिससे वह विरासत में नहीं पा सकता है।
इस उदाहरण में दो फाइलें हैं: असेम्बली 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
जब आपके पास विधियां, कक्षाएं आदि होती हैं, जिन्हें वर्तमान विधानसभा के दायरे में पहुंच योग्य होना चाहिए और इसके बाहर कभी नहीं।
उदाहरण के लिए, एक डीएएल में एक ओआरएम हो सकता है, लेकिन वस्तुओं को व्यावसायिक परत के संपर्क में नहीं आना चाहिए, सभी इंटरैक्शन स्थिर विधियों के माध्यम से और आवश्यक पैरामटर्स में पास होना चाहिए।
आंतरिक का एक बहुत ही रोचक उपयोग - बेशक आंतरिक सदस्य केवल उस विधानसभा तक सीमित है जिसमें यह घोषित किया गया है - इसमें से कुछ हद तक "मित्र" कार्यक्षमता प्राप्त कर रहा है। एक मित्र सदस्य कुछ ऐसा है जो केवल विधानसभा के बाहर कुछ अन्य विधानसभाओं में दिखाई देता है जिसमें इसकी घोषणा की गई है। C # मित्र के समर्थन में नहीं बनाया गया है, हालांकि CLR करता है।
आप दोस्त सभा की घोषणा करने के लिए InternalsVoubleToAttribute का उपयोग कर सकते हैं , और मित्र विधानसभा के भीतर से सभी संदर्भ आपके विधानसभा के आंतरिक सदस्यों को मित्र विधानसभा के दायरे में सार्वजनिक रूप से व्यवहार करेंगे। इसके साथ एक समस्या यह है कि सभी आंतरिक सदस्य दिखाई देते हैं; आप चुन और चुन नहीं सकते।
इंटरनल्सविजयोटी के लिए एक अच्छा उपयोग विभिन्न आंतरिक सदस्यों को एक यूनिट टेस्ट असेंबली में उजागर करना है, इस प्रकार उन सदस्यों का परीक्षण करने के लिए जटिल प्रतिबिंब के काम की जरूरतों को समाप्त करना है। सभी आंतरिक सदस्य दिखाई दे रहे हैं, इसलिए इसमें कोई समस्या नहीं है, लेकिन इस दृष्टिकोण को लेने से आपकी कक्षा में बहुत अधिक अंतर पैदा हो जाता है और संभावित रूप से विधानसभा के भीतर इनकैप्सुलेशन को बर्बाद कर सकता है।
नियम के रूप में अंगूठे के दो प्रकार के सदस्य होते हैं:
शोर में कमी, आपके पुस्तकालय जितना सरल है उतने कम प्रकार को उजागर करते हैं। टेम्पर प्रूफिंग / सुरक्षा एक और है (हालांकि प्रतिबिंब इसके खिलाफ जीत सकता है)।
आंतरिक कक्षाएं आपको अपनी विधानसभा के एपीआई को सीमित करने में सक्षम बनाती हैं। यह आपके एपीआई को समझने के लिए सरल बनाने की तरह लाभ है।
इसके अलावा, यदि आपकी विधानसभा में बग मौजूद है, तो ब्रेकिंग परिवर्तन को शुरू करने वाले फिक्स की संभावना कम है। आंतरिक कक्षाओं के बिना, आपको यह मानना होगा कि किसी भी वर्ग के सार्वजनिक सदस्यों को बदलना एक परिवर्तन होगा। आंतरिक कक्षाओं के साथ, आप मान सकते हैं कि उनके सार्वजनिक सदस्यों को संशोधित करने से केवल विधानसभा की आंतरिक एपीआई (और किसी भी असेंबली इंटरनैशनलविस्टो विशेषता में संदर्भित) टूट जाती है।
मुझे क्लास लेवल और असेंबली लेवल पर इनकैप्सुलेशन होना पसंद है। कुछ ऐसे हैं जो इससे सहमत नहीं हैं, लेकिन यह जानना अच्छा है कि कार्यक्षमता उपलब्ध है।
मेरे पास एक प्रोजेक्ट है जो डेटा बैक-एंड के लिए 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
है, और यह काफी उपयोगी साबित हो रहा है।
ऐसे मामले हैं जब यह वर्गों के सदस्यों को बनाने के लिए समझ में आता है internal
। एक उदाहरण यह हो सकता है कि यदि आप यह नियंत्रित करना चाहते हैं कि कक्षाएं कैसे त्वरित हैं; मान लीजिए कि आप वर्ग के उदाहरण बनाने के लिए किसी प्रकार का कारखाना प्रदान करते हैं। आप कंस्ट्रक्टर बना सकते हैंinternal
, ताकि फैक्ट्री (जो एक ही असेंबली में रहती है) क्लास के उदाहरण बना सकते हैं, लेकिन उस असेंबली के बाहर कोड नहीं हो सकता।
हालाँकि, मैं internal
विशिष्ट कारणों के बिना कक्षाओं या सदस्यों को बनाने के साथ कोई भी बिंदु नहीं देख सकता , बस उतना ही कम है जितना उन्हें बनाने के लिए public
या private
विशिष्ट कारणों के बिना समझ में आता है ।
केवल एक चीज जो मैंने कभी आंतरिक कीवर्ड का उपयोग किया है, वह है मेरे उत्पाद में लाइसेंस-चेकिंग कोड ;-)
आंतरिक कीवर्ड का एक उपयोग आपके विधानसभा के उपयोगकर्ता से ठोस कार्यान्वयन तक पहुंच को सीमित करना है।
यदि आपके पास कोई निर्माण करने के लिए कोई कारखाना या कोई अन्य केंद्रीय स्थान है, तो आपके विधानसभा के उपयोगकर्ता को केवल सार्वजनिक इंटरफ़ेस या सार आधार वर्ग से निपटने की आवश्यकता है।
इसके अलावा, आंतरिक कंस्ट्रक्टर आपको नियंत्रित करने की अनुमति देते हैं कि कहां और कब एक अन्यथा सार्वजनिक वर्ग को तत्काल दिया जाए।
यह कैसे होता है: आमतौर पर यह अनुशंसा की जाती है कि आप किसी असेंबली के बाहरी उपयोगकर्ताओं के लिए सूची ऑब्जेक्ट को उजागर नहीं करते हैं, बल्कि एक IEnumerable को उजागर करते हैं। लेकिन असेंबली के अंदर एक सूची ऑब्जेक्ट का उपयोग करना बहुत आसान है, क्योंकि आपको सरणी सिंटैक्स, और अन्य सभी सूची विधियां मिलती हैं। इसलिए, मेरे पास आमतौर पर विधानसभा के अंदर उपयोग की जाने वाली सूची को उजागर करने वाली एक आंतरिक संपत्ति है।
इस दृष्टिकोण के बारे में टिप्पणियों का स्वागत है।
ध्यान रखें कि किसी भी वर्ग के रूप में परिभाषित public
स्वचालित रूप से इंटेलीजेंस में दिखाई देगा जब कोई आपके प्रोजेक्ट नामस्थान को देखता है। एपीआई के नजरिए से, आपके प्रोजेक्ट के उपयोगकर्ताओं को केवल उन कक्षाओं को दिखाना जरूरी है, जिनका वे उपयोग कर सकते हैं। उपयोगinternal
चीज़ों को छिपाने के कीवर्ड का जिन्हें उन्हें नहीं देखना चाहिए।
यदि आपका Big_Important_Class
प्रोजेक्ट ए के लिए आपकी परियोजना के बाहर उपयोग करने का इरादा है, तो आपको इसे चिह्नित नहीं करना चाहिएinternal
।
हालाँकि, कई परियोजनाओं में, आपके पास अक्सर ऐसी कक्षाएं होंगी जो वास्तव में केवल एक परियोजना के अंदर उपयोग के लिए होती हैं। उदाहरण के लिए, आपके पास एक वर्ग हो सकता है जो एक पैरामीटर थ्रेड आह्वान के लिए तर्क रखता है। इन मामलों में, आपको उन्हें ऐसे चिह्नित करना चाहिए जैसे internal
कि बिना किसी अन्य कारण के बिना किसी अनचाहे एपीआई से खुद को बचाने के लिए सड़क को बदल दें।
private
कीवर्ड केवल कक्षाओं या structs कि एक और वर्ग या struct के भीतर परिभाषित कर रहे हैं पर इस्तेमाल किया जा सकता है। एक नाम स्थान के भीतर परिभाषित एक वर्ग केवल घोषित किया जा सकता है public
या internal
।
यह विचार यह है कि जब आप केवल एक पुस्तकालय डिजाइन कर रहे हों तो बाहर से उपयोग के लिए अभिप्रेत कक्षाएं (आपके पुस्तकालय के ग्राहकों द्वारा) सार्वजनिक होनी चाहिए। इस तरह आप उन कक्षाओं को छिपा सकते हैं जो
आदि।
यदि आप आंतरिक तत्वों का उपयोग करने की तुलना में इनडोर समाधान विकसित कर रहे हैं, तो यह महत्वपूर्ण नहीं है कि मुझे लगता है, क्योंकि आमतौर पर ग्राहकों का आपके साथ निरंतर संपर्क और / या कोड तक पहुंच होगी। वे हालांकि पुस्तकालय डेवलपर्स के लिए काफी महत्वपूर्ण हैं।
जब आपके पास कक्षाएं या विधियाँ हैं जो ऑब्जेक्ट-ओरिएंटेड प्रतिमान में सफाई से फिट नहीं होती हैं, जो खतरनाक सामान करते हैं, जिसे आपके नियंत्रण में अन्य वर्गों और विधियों से बुलाया जाना चाहिए, और जिसे आप किसी और का उपयोग नहीं करने देना चाहते हैं ।
public class DangerousClass {
public void SafeMethod() { }
internal void UpdateGlobalStateInSomeBizarreWay() { }
}