दिलचस्प पोस्ट
एक अभी-अभी-समय (जेआईटी) कंपाइलर क्या करता है? सी ++ में स्ट्रिंग को बदलने में सबसे आसान तरीका आईओएस में एक यूआईटीक्श्वेव्यू में अनुवादित पाठ पर नल का पता लगा रहा है "आधुनिक" रेगेक्सस की मान्यता शक्ति मैं FileList से एक फ़ाइल को कैसे निकालूं? जावास्क्रिप्ट में क्रॉस ब्राउजर फ्लैश डिटेक्शन स्थानीय JSON फ़ाइल लोड हो रही है क्या "argv = नाम-निष्पादनयोग्य" स्वीकृत मानक या सिर्फ एक आम सम्मेलन है? रेल पर रूबी में, मैं "वें" प्रत्यय के साथ दिनांक को कैसे प्रारूपित कर सकता हूं, जैसे "सूर्य 5 अक्टूबर"? String.split पाइप सीमांकक को बचने की आवश्यकता क्यों है? स्क्रीन चमक को प्रोग्रामेटिक रूप से परिवर्तित करना (पावर विजेट के साथ) PHP फ़ंक्शन कॉल करने के लिए jquery $ .ajax का उपयोग कर गतिविधि समूह के अंदर एक टुकड़ा के साथ एक टुकड़ा की जगह WordPress में और अधिक पोस्ट्स अजाक्स बटन लोड करें त्रुटि संदेश: पीडीबी फ़ाइल को ढूंढ या खोल नहीं सकता

C # को सी ++ शैली 'मित्र' कीवर्ड क्यों नहीं प्रदान करता है?

सी + + मित्र कीवर्ड एक class A को class B को अपने दोस्त के रूप में निर्दिष्ट करने की अनुमति देता है यह Class B को Class B के private / protected सदस्यों तक पहुंचने में सहायता करता है।

मैंने कभी भी कुछ भी नहीं पढ़ा है क्योंकि इसे सी # (और वीबीनेट) से बाहर छोड़ दिया गया था। इससे पहले स्टैक ओव्हरफ्लो प्रश्न के अधिकांश उत्तर यह कह रहे हैं कि यह सी ++ का एक उपयोगी हिस्सा है और इसका उपयोग करने के लिए अच्छे कारण हैं। मेरे अनुभव में मुझे सहमत होना होगा।

एक और सवाल यह है कि मैं सचमुच पूछ रहा हूं कि सी # एप्लिकेशन में friend समान कुछ कैसे करें। जबकि जवाब आम तौर पर नेस्टेड कक्षाओं के चारों ओर घूमते हैं, लेकिन यह friend कीवर्ड का उपयोग करने के रूप में काफी प्रतीत नहीं होता है।

मूल डिज़ाइन पैटर्न पुस्तकों का उपयोग इसके अपने उदाहरणों में नियमित रूप से करता है

तो संक्षेप में, friend सी # से गायब क्यों नहीं है, और सी # में अनुकरण करने का "सर्वोत्तम अभ्यास" तरीका (या तरीके) क्या है?

(वैसे, internal खोजशब्द एक ही बात नहीं है, यह पूरे विधानसभा के अंदर सभी वर्गों को internal सदस्यों तक पहुंचने की अनुमति देता है, जबकि friend आपको एक दूसरे वर्ग के लिए एक निश्चित कक्षा पूर्ण पहुंच प्रदान करने की अनुमति देता है)

वेब के समाधान से एकत्रित समाधान "C # को सी ++ शैली 'मित्र' कीवर्ड क्यों नहीं प्रदान करता है?"

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

कहा जा रहा है कि, यह एक अच्छी सुविधा है और मैंने इसे सी ++ में अपने आप में बहुत समय का प्रयोग किया है; और इसे सी # में भी इस्तेमाल करना चाहेंगे लेकिन मैं शर्त लगा सकता हूं कि सी # के "शुद्ध" ओऑनेस (सी ++ के छद्म ओओनेस की तुलना में) ने तय किया है कि जावा के पास कोई दोस्त की खोजशब्द नहीं है सी # को या तो नहीं करना चाहिए (बस मजाक कर रहे हैं;))

एक गंभीर नोट पर: आंतरिक दोस्त के रूप में उतना ही अच्छी नहीं है, लेकिन यह काम पूरा करता है। याद रखें कि यह दुर्लभ है कि आप 3 डी डेवलपर्स को अपना कोड वितरित करेंगे, हालांकि कोई DLL नहीं; इसलिए जब तक आप और आपकी टीम आंतरिक कक्षाओं के बारे में जानते हैं और उनका उपयोग ठीक हो जाना चाहिए।

संपादित करें मुझे स्पष्ट करें कि मित्र कीवर्ड OOP को कैसे अपमानित करता है

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

एक और बात। दोस्त का प्रयोग इनकैप्समलेशन का उल्लंघन करने के बारे में नहीं है, बल्कि इसके विपरीत यह इसे लागू करने के बारे में है एक्सेसर्स + म्यूटेटर, ऑपरेटर्स ओवरलोडिंग, पब्लिक हिरासत, डाउनकास्टिंग इत्यादि की तरह , इसका अक्सर दुरुपयोग किया जाता है, लेकिन इसका मतलब यह नहीं है कि कीवर्ड की कोई और भी बदतर, खराब उद्देश्य नहीं है।

अन्य धागे में कोनराड रूडोल्फ का संदेश देखें, या यदि आप सी ++ अकसर किये गए सवाल में संबंधित प्रविष्टि को देखना पसंद करते हैं

जानकारी के लिए, एनएटी में एक और संबंधित-पर-काफी-कुछ नहीं है [InternalsVisibleTo] , जो एक विधानसभा को एक और विधानसभा को डिज़ाइन करने देता है (जैसे कि एक इकाई परीक्षण विधानसभा) जो (प्रभावी रूप से) प्रकारों तक "आंतरिक" पहुंच है / मूल विधानसभा में सदस्य

आपको सी # में इंटरफेस का उपयोग करके सी ++ में "मित्र" का उपयोग करने के लिए उसी प्रकार की चीजों को पूरा करने में सक्षम होना चाहिए इसके लिए आपको स्पष्ट रूप से परिभाषित करना होगा कि कौन से सदस्यों को दो वर्गों के बीच पारित किया जा रहा है, जो अतिरिक्त काम है, लेकिन यह भी समझने में आसान कोड बना सकता है।

अगर किसी व्यक्ति के "दोस्त" के उचित उपयोग का एक उदाहरण है जो इंटरफेस का उपयोग करके नकली नहीं किया जा सकता है, तो कृपया इसे साझा करें! मैं C ++ और C # के बीच अंतर को बेहतर ढंग से समझना चाहता हूं

friend साथ एक सी + + डिजाइनर के पास सटीक नियंत्रण होता है, जिनके साथ निजी * सदस्य हैं। लेकिन, वह निजी सदस्यों में से हर एक का पर्दाफाश करने के लिए मजबूर है।

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

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

जैसा कि आप देख सकते हैं, हमारे पास 2 आयाम हैं जिनमें इनकपेशूल का उल्लंघन किया जा सकता है। friend इसे एक आयाम के साथ तोड़ता है, internal दूसरे के साथ करता है एनकैप्सुलेशन अवधारणा में कौन सा एक बुरा उल्लंघन है? बताना कठिन है। लेकिन यह दोनों friend और internal उपलब्ध दोनों के लिए अच्छा होगा इसके अलावा, इन दोनों को एक अच्छी जोड़ी होगी जो कि तीसरे प्रकार के कीवर्ड होंगे, जिनका उपयोग सदस्य-सदस्य-सदस्य आधार ( internal ) पर किया जाएगा और लक्ष्य वर्ग (जैसे friend ) को निर्दिष्ट करेगा

* संक्षेप के लिए मैं "निजी और / या संरक्षित" की जगह "निजी" का उपयोग करूँगा।

– निक

आप सी # कीवर्ड "आंतरिक" के साथ C ++ "मित्र" के करीब मिल सकते हैं।

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

कहा जा रहा है कि मुझे लगता है कि नेल्सन के पास एक अच्छी व्याख्या है कि यह एक बुरी चीज क्यों है।

यूनिट टेस्ट लिखते समय मित्र अत्यंत उपयोगी होते हैं I

यद्यपि यह आपके वर्ग की घोषणा को थोड़ा संदूषित करने की लागत पर आता है, यह कम्पाइलर-लागू अनुस्मारक भी है कि वास्तव में कक्षा की आंतरिक स्थिति के बारे में क्या जांच हो सकती है।

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

सी # में इसके "दोस्त" कीवर्ड को उसी कारण से गुम है, जिसकी वजह से इसकी यादृच्छिक नियतात्मक विनाश है। सम्मेलनों में परिवर्तन करना लोगों को चतुर लगता है, जैसे कि उनके नए तरीके किसी और से 'पुराने तरीके से श्रेष्ठ हैं। यह गर्व के बारे में है

यह कहते हुए कि "मित्र वर्ग खराब हैं" जैसे अन्य अयोग्य बयानों के रूप में "गोटो का उपयोग न करें" या "लिनक्स विंडोज से बेहतर है" के रूप में लघु दृष्टि से है

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

वास्तव में, सी # बिना किसी विशेष शब्दों के शुद्ध ओप तरीके से समान व्यवहार करने की संभावना देता है – यह निजी इंटरफेस है

जहाँ तक सवाल है सी # दोस्त के बराबर है? इस अनुच्छेद में डुप्लिकेट के रूप में चिह्नित किया गया था और कोई भी वास्तव में अच्छी प्राप्ति का प्रस्ताव नहीं करता – मैं यहां दोनों प्रश्नों पर उत्तर दिखाएगा।

मुख्य विचार यहां से ले रहा था: निजी इंटरफेस क्या है?

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

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

आप ऐसा कर सकते हैं:

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

Controller.cs

 public class Controller { private interface IState { void Update(); } public class StateBase : IState { void IState.Update() { } } public Controller() { //it's only way call Update is to cast obj to IState IState obj = new StateBase(); obj.Update(); } } 

Program.cs

 class Program { static void Main(string[] args) { //it's impossible to write Controller.IState p = new StateBase(); //Controller.IState is hidden StateBase p = new StateBase(); //p.Update(); //is not accessible } } 

खैर, विरासत के बारे में क्या?

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

Controller.cs

 public class Controller { protected interface IState { void Update(); } public class StateBase : IState { void IState.Update() { OnUpdate(); } protected virtual void OnUpdate() { Console.WriteLine("StateBase.OnUpdate()"); } } public Controller() { IState obj = new PlayerIdleState(); obj.Update(); } } 

PlayerIdleState.cs

 public class PlayerIdleState: Controller.StateBase { protected override void OnUpdate() { base.OnUpdate(); Console.WriteLine("PlayerIdleState.OnUpdate()"); } } 

और आखिरकार उदाहरण के लिए कैसे क्लास नियंत्रक को फेंकने का परीक्षण करें: कंट्रोलरटैस्ट.cs

 class ControllerTest: Controller { public ControllerTest() { IState testObj = new PlayerIdleState(); testObj.Update(); } } 

आशा है कि मैं सभी मामलों को कवर करता हूं और मेरा उत्तर उपयोगी था।

इस सीमा के लिए बहाने बनाने बंद करो दोस्त बुरा है, लेकिन आंतरिक अच्छा है? वे एक ही बात है, केवल उस दोस्त को आप पर अधिक सटीक नियंत्रण देता है कि कौन कौन से प्रवेश करने की अनुमति है और कौन नहीं है।

यह इनकैप्सुलेशन प्रतिमान को लागू करना है? तो आपको एक्सेसर तरीके लिखने होंगे और अब क्या होगा? इन विधियों को कॉल करने से आप सभी को कैसे रोक सकते हैं (कक्षा बी के तरीकों को छोड़कर)? आप ऐसा नहीं कर सकते हैं, क्योंकि आप "मित्र" गुम होने के कारण इसे नियंत्रित नहीं कर सकते हैं

कोई प्रोग्रामिंग भाषा सही नहीं है सी # मैंने देखा है सर्वोत्तम भाषाओं में से एक है, लेकिन लापता सुविधाओं के लिए मूर्खतापूर्ण बहाने बनाने से किसी को भी मदद नहीं मिलती सी ++ में, मैं आसान घटना / प्रतिनिधि प्रणाली, प्रतिबिंब (+ स्वत: डे / क्रमबद्धता) और foreach याद आती है, लेकिन सी # में मैं ऑपरेटर ओवरलोडिंग को याद करता हूं (हाँ, मुझे बताते रहें कि आपको इसकी आवश्यकता नहीं है), डिफ़ॉल्ट पैरामीटर, एक कॉन्स्ट कि, circumvented नहीं किया जा सकता है, एकाधिक विरासत (हाँ, मुझे कह रही है कि आपको इसकी ज़रूरत नहीं थी और इंटरफेस एक पर्याप्त प्रतिस्थापन थे) और क्षमता स्मृति से एक उदाहरण को हटाने का फैसला (नहीं, यह बुरी तरह बुरा नहीं है जब तक आप tinkerer)

नॉट 3 के बाद से आंतरिकस्वास्थ्यताओटेटिवेटिव है लेकिन मुझे संदेह है कि वे केवल इसे इकाई परीक्षण के उत्थान के बाद परीक्षण असेंबलियों को पूरा करने के लिए जोड़ा था। मैं इसका इस्तेमाल करने के लिए कई अन्य कारणों को नहीं देख सकता।

यह विधानसभा स्तर पर काम करता है लेकिन यह ऐसा काम करता है जहां आंतरिक नहीं होता है; वह है, जहां आप एक विधानसभा वितरित करना चाहते हैं, लेकिन एक अन्य गैर-वितरित विधानसभा को इसे एक्सेस करने के लिए विशेषाधिकार प्राप्त करना चाहते हैं।

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

मैंने "दोस्त" कीवर्ड के बारे में कई स्मार्ट टिप्पणियां पढ़ ली हैं और मैं इससे सहमत हूं कि यह उपयोगी चीज है, लेकिन मुझे लगता है कि "आंतरिक" कीवर्ड कम उपयोगी है, और वे दोनों शुद्ध ओओ प्रोग्रामिंग के लिए भी खराब हैं I

हमारे पास क्या है? ("दोस्त" के बारे में कह रही हूं, मैं "आंतरिक" के बारे में भी कह रहा हूं)

  • "मित्र" का प्रयोग कर रहा है, वो के बारे में कोड कम शुद्ध करता है?
  • हाँ;

  • "मित्र" का उपयोग नहीं कर रहा है, कोड बेहतर बनाता है?

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

मित्र का उपयोग करना कुछ स्थानीय समस्याएं पैदा करता है, इसका उपयोग नहीं करता, कोड-लाइब्रेरी-उपयोगकर्ताओं के लिए समस्याएं पैदा करता है

प्रोग्रामिंग भाषा के लिए आम अच्छा समाधान मैं इस तरह देख रहा हूँ:

 // c++ style class Foo { public_for Bar: void addBar(Bar *bar) { } public: private: protected: }; // c# class Foo { public_for Bar void addBar(Bar bar) { } } 

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

मुझे संदेह है कि यह सी # संकलन मॉडल के साथ कुछ करना है – आईआईएल जेआईटी का संकलन क्रमबद्ध समय पर करता है। यानी: एक ही कारण है कि सी # जेनेरिक मूलभूत रूप से सी ++ जेनेरिक के लिए अलग हैं

यदि आप सी ++ के साथ काम कर रहे हैं और आप दोस्त खोजशब्द का इस्तेमाल करते हुए अपना स्वयं का पता लगाते हैं, तो यह एक बहुत मजबूत संकेत है, कि आपके पास डिज़ाइन समस्या है, क्योंकि क्लास को अन्य वर्ग के निजी सदस्यों तक पहुंचने की आवश्यकता क्यों है ??

आप इसे निजी रख सकते हैं और कार्यों को कॉल करने के लिए प्रतिबिंब का उपयोग कर सकते हैं। टेस्ट फ्रेमवर्क ऐसा कर सकते हैं यदि आप इसे एक निजी फ़ंक्शन का परीक्षण करने के लिए कहते हैं

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

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

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

क्या लोग जानते हैं कि आप विशेषता, संपत्ति, और विधि स्तर पर आंतरिक खोजशब्द लागू कर सकते हैं? यह केवल शीर्ष स्तर के वर्ग घोषणापत्र के लिए नहीं है (हालांकि अधिकांश उदाहरण यह दिखाते हैं।)

अगर आपके पास एक सी + क्लास है जो मित्र कीवर्ड का उपयोग करता है, और इसे सी # वर्ग में अनुकरण करना चाहता है: 1. सी # वर्ग सार्वजनिक घोषित करें। C ++ में संरक्षित सभी विशेषताएँ / गुण / विधियां घोषित करें और इस तरह से दोस्तों के लिए सुलभ हैं आंतरिक में सी # 3. सभी आंतरिक विशेषताओं और गुणों के लिए सार्वजनिक पहुंच के लिए केवल पढ़ने के गुण बनाएँ

मैं सहमत हूं कि यह 100% दोस्त के समान नहीं है, और यूनिट टेस्ट मित्र की तरह कुछ की ज़रूरत का एक बहुत ही महत्वपूर्ण उदाहरण है (जैसा कि प्रोटोकॉल विश्लेषक लॉगिंग कोड है)। हालांकि आंतरिक उन वर्गों के संपर्क को प्रदान करता है जिन्हें आप एक्सपोजर चाहते हैं, और [आंतरिकवविस्त्य ()] आराम से संभालता है – ऐसा लगता है कि यह विशेष रूप से यूनिट टेस्ट के लिए पैदा हुआ था

जहां तक ​​मित्र "बेहतर होता है क्योंकि आप स्पष्ट रूप से नियंत्रित कर सकते हैं कि किस वर्ग के पास पहुंच है" – क्या संवेदक बुरा वर्गों का एक समूह पहली जगह में उसी विधानसभा में कर रहा है? अपने विधानसभाओं का विभाजन!

दोस्ती इंटरफेस और कार्यान्वयन को अलग करके सिम्युटेड हो सकती है। विचार यह है: " एक ठोस उदाहरण की आवश्यकता है, लेकिन उस उदाहरण के निर्माण का उपयोग प्रतिबंधित है "।

उदाहरण के लिए

 interface IFriend { } class Friend : IFriend { public static IFriend New() { return new Friend(); } private Friend() { } private void CallTheBody() { var body = new Body(); body.ItsMeYourFriend(this); } } class Body { public void ItsMeYourFriend(Friend onlyAccess) { } } 

इस तथ्य के बावजूद कि ItsMeYourFriend() केवल सार्वजनिक ही Friend वर्ग इसे एक्सेस कर सकती है, क्योंकि किसी और को Friend क्लास का कोई ठोस उदाहरण नहीं मिल सकता है। इसकी एक निजी निर्माता है, जबकि फ़ैक्ट्री New() विधि इंटरफ़ेस देता है।

विवरण के लिए इंटरफेस को कोडिंग के साथ मेरे लेख दोस्तों और आंतरिक इंटरफ़ेस सदस्यों को बिना किसी कीमत पर देखें

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

मेरे पास एक asp.net पेज है जो मेरे अपने बेस पेज को संभालता है, जो बदले में सिस्टम। इस पृष्ठ में, मेरे पास कुछ कोड है जो एप्लिकेशन के लिए एंड-यूज़र त्रुटि रिपोर्टिंग को सुरक्षित तरीके से प्रबंधित करता है

 ReportError("Uh Oh!"); 

अब, मेरे पास उपयोगकर्ता नियंत्रण है जो पेज में शामिल है I मैं चाहता हूं कि उपयोगकर्ता नियंत्रण पृष्ठ पर त्रुटि रिपोर्टिंग विधियों को कॉल करने में सक्षम हो।

 MyBasePage bp = Page as MyBasePage; bp.ReportError("Uh Oh"); 

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

 protected void ReportError(string str) { MyBasePage bp = Page as MyBasePage; bp.ReportError(str); } 

मेरा मानना ​​है कि मित्र की तरह कुछ उपयोगी हो सकता है और भाषा को "ओ" जैसी कम भाषा के बिना, विशेषताओं के रूप में कम कर दिया जा सकता है, ताकि आप वर्ग या विधियां विशिष्ट वर्गों या विधियों के लिए मित्र बन सकें, जिससे डेवलपर को बहुत विशिष्ट पहुंच शायद कुछ ऐसा … (छद्म कोड)

 [Friend(B)] class A { AMethod() { } [Friend(C)] ACMethod() { } } class B { BMethod() { A.AMethod() } } class C { CMethod() { A.ACMethod() } } 

मेरे पिछले उदाहरण के मामले में शायद निम्नलिखित की तरह कुछ है (एक शब्दों को बहस कर सकता है, लेकिन मैं बस इस विचार को प्राप्त करने की कोशिश कर रहा हूं):

 class BasePage { [Friend(BaseControl.ReportError(string)] protected void ReportError(string str) { } } class BaseControl { protected void ReportError(string str) { MyBasePage bp = Page as MyBasePage; bp.ReportError(str); } } 

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

bsd

यह कहा गया था कि, दोस्तों ने शुद्ध ओओनेस को दर्द पहुंचाया है जो मैं सहमत हूँ

यह भी कहा गया है कि दोस्तों को इनकैप्सुलेशन में मदद मिलती है, जिसे मैं भी सहमत हूं।

मुझे लगता है कि दोस्ती को ओ ओ कार्यप्रणाली में जोड़ा जाना चाहिए, लेकिन सी ++ में काफी नहीं। मुझे कुछ फ़ील्ड / तरीके हैं जो मेरी मित्र कक्षा का उपयोग कर सकते हैं, लेकिन मैं उन्हें अपने सभी क्षेत्रों / तरीकों तक पहुंचने के लिए पसंद नहीं करना चाहता था वास्तविक जीवन की तरह, मैं अपने दोस्तों को अपने व्यक्तिगत रेफ्रिजरेटर तक पहुंचने देता था लेकिन मैं उन्हें अपने बैंक खाते तक पहुंचने नहीं देना चाहता था।

एक के रूप में लागू किया जा सकता है कि पीछा किया

  class C1 { private void MyMethod(double x, int i) { // some code } // the friend class would be able to call myMethod public void MyMethod(FriendClass F, double x, int i) { this.MyMethod(x, i); } //my friend class wouldn't have access to this method private void MyVeryPrivateMethod(string s) { // some code } } class FriendClass { public void SomeMethod() { C1 c = new C1(); c.MyMethod(this, 5.5, 3); } } 

That will of course generate a compiler warning, and will hurt the intellisense. But it will do the work.

On a side note, I think that a confident programmer should do the testing unit without accessing the private members. this is quite out of the scope, but try to read about TDD. however, if you still want to do so (having c++ like friends) try something like

 #if UNIT_TESTING public #else private #endif double x; 

so you write all your code without defining UNIT_TESTING and when you want to do the unit testing you add #define UNIT_TESTING to the first line of the file(and write all the code that do the unit testing under #if UNIT_TESTING). That should be handled carefully.

Since I think that unit testing is a bad example for the use of friends, I'd give an example why I think friends can be good. Suppose you have a breaking system (class). With use, the breaking system get worn out and need to get renovated. Now, you want that only a licensed mechanic would fix it. To make the example less trivial I'd say that the mechanic would use his personal (private) screwdriver to fix it. That's why mechanic class should be friend of breakingSystem class.

The friendship may also be simulated by using "agents" – some inner classes. निम्नलिखित उदाहरण पर विचार करें:

 public class A // Class that contains private members { private class Accessor : B.BAgent // Implement accessor part of agent. { private A instance; // A instance for access to non-static members. static Accessor() { // Init static accessors. B.BAgent.ABuilder = Builder; B.BAgent.PrivateStaticAccessor = StaticAccessor; } // Init non-static accessors. internal override void PrivateMethodAccessor() { instance.SomePrivateMethod(); } // Agent constructor for non-static members. internal Accessor(A instance) { this.instance = instance; } private static A Builder() { return new A(); } private static void StaticAccessor() { A.PrivateStatic(); } } public A(B friend) { B.Friendship(new A.Accessor(this)); } private A() { } // Private constructor that should be accessed only from B. private void SomePrivateMethod() { } // Private method that should be accessible from B. private static void PrivateStatic() { } // ... and static private method. } public class B { // Agent for accessing A. internal abstract class BAgent { internal static Func<A> ABuilder; // Static members should be accessed only by delegates. internal static Action PrivateStaticAccessor; internal abstract void PrivateMethodAccessor(); // Non-static members may be accessed by delegates or by overrideable members. } internal static void Friendship(BAgent agent) { var a = BAgent.ABuilder(); // Access private constructor. BAgent.PrivateStaticAccessor(); // Access private static method. agent.PrivateMethodAccessor(); // Access private non-static member. } } 

It could be alot simpler when used for access only to static members. Benefits for such implementation is that all the types are declared in the inner scope of friendship classes and, unlike interfaces, it allows static members to be accessed.

Fields that ALL classes can access them are public .

Fields that NOT all other classes can access them are private .

(if the fields belongs to (declared inside) base class, then they are protected instead)

Fields that only their owner class can access them are private , and have no properties and get set methods.

Fields that only their owner class and some other classes can access them are private and each has special private get and set methods, and public share methods.

The some other classes that can also access these fields will have some private fields of delegate types and special public direct methods.

उदाहरण:

 using System; class A { private int integer; //In the meantime, it seems that only A can access this integer private int GetInteger() //Get method is not public, because we don't want all other classes to use this integer { return this.integer; } private void SetInteger(int value) //Set method is not public, because we don't want all other classes to modify this integer { this.integer = value; } public void Share(ref B b) //I use the 'ref' keyword, to prevent the 'null' value in this argument, but if you call this method in a constructor of B, or in one of its methods, so you will have to remove the 'ref' keyword, or make overload of the same method without the 'ref' keyword, because 'ref this' is not allowed { b.DirectGetIntegerAndSetIntegerMethods(this.GetInteger, this.SetInteger); } public void PrintInteger() { Console.WriteLine(this.integer); } } class B //This class can access the 'integer' of A too, ie the 'integer' of A is "public" only for B { private Func<int> GetInteger; //Will execute the 'GetInteger' method of A private Action<int> SetInteger; //Will execute the 'SetInteger' method of A public void DirectGetIntegerAndSetIntegerMethods(Func<int> getInteger, Action<int> setInteger) { this.GetInteger = getInteger; this.SetInteger = setInteger; } public void Increment() { this.SetInteger(this.GetInteger() + 1); } } class Program { static void Main(string[] args) { A a = new A(); //Created new instance of A, and also new Int32 was initialized inside it and set to its default value 0, but unable to get or set its value, only just print it. a.PrintInteger(); B b = new B(); //Must create new instance of B, in order to change the integer of A to some value. For example, I will use b, to change the integer of a to 3 a.Share(ref b); //But before the change, I must tell 'a' to share his GetInteger and SetInteger methods to 'b', so 'b' will also be able execute them, through his Func<int> and Action<int> delegates, because GetInteger and SetInteger methods of A are private and cannot be executed directly. for (int i = 0; i < 3; i++) b.Increment(); a.PrintInteger(); //Print the integer of 'a' again after change. //Now the output of the console is: //0 //3 } } 

You have to know that using the 'friend' keyword of the C++ is to allow some classes to share their private members to some other classes directly .

Because of that the 'friend' keyword doesn't exist in C#, classes have no way to share their private fields to some other classes directly , but there is way to simulate it indeed as I shown above.

Do you know that the 'friend' keyword of C++ also can allow in the implementation of some functions to access the private members of some instances of some classes types?

The answer is yes and I will show you how to simulate this too in C#:

उदाहरण:

 using System; using System.Reflection; //New namespace is added using System.Diagnostics; //Another new namespace is added too class Person { private readonly StackTrace st = new StackTrace(); //Helper object private readonly MethodInfo mi = typeof(Program).GetMethod("Foo"); //The MethodInfo of the method Foo, which will be declared and defined in class Program later, is the friend of the class Person //Both objects above are readonly, because they always reference the same objects that they were initialized with. private string name_of_his_dog; //Only Person can access this field private string GetTheNameOfHisDog() //Not public so that not all methods will be able to get this name { return this.name_of_his_dog; } private void SetTheNameOfHisDog(string new_name) //Not public so that not all methods will be able to set this name { this.name_of_his_dog = new_name; } public Func<string> ShareTheGetTheNameOfHisDogMethod() //Returns null, if the previous method that called this method is not friend of this class Person { if (this.st.GetFrame(1).GetMethod() == this.mi) return this.GetTheNameOfHisDog; return null; } public Action<string> ShareTheSetTheNameOfHisDogMethod() //Same as above { if (this.st.GetFrame(1).GetMethod() == this.mi) return this.SetTheNameOfHisDog; return null; } public void PrintTheNameOfHisDog() { Console.WriteLine(this.name_of_his_dog); } } class Program { static void Main(string[] args) { Person person = Foo(); person.PrintTheNameOfHisDog(); Func<string> getTheNameOfHisDog = person.ShareTheGetTheNameOfHisDogMethod(); //returns null, Main is not friend of Person Action<string> setTheNameOfHisDog = person.ShareTheSetTheNameOfHisDogMethod(); //returns null too, for the same reason setTheNameOfHisDog("Pointer"); //Runtime Error: Object reference not set to an instance of an object Console.WriteLine(getTheNameOfHisDog()); //Same runtime error //Output before runtime error: //Boxer //Boxer } public static Person Foo() //Only this method can get and set the name of the dog that belongs to the person { Person person = new Person(); Func<string> getTheNameOfHisDog = person.ShareTheGetTheNameOfHisDogMethod(); Action<string> setTheNameOfHisDog = person.ShareTheSetTheNameOfHisDogMethod(); setTheNameOfHisDog("Boxer"); Console.WriteLine(getTheNameOfHisDog()); return person; } } 

I must admit that before I posted this code, I didn't know how to find out the MethodInfo of the previous method that called the current method, but Firas Assaad's answer helped me, thanks to him too.

मैं वर्तमान पद्धति को बुलाए जाने वाली विधि कैसे पा सकता हूँ?

He suggested to use the System.Diagnostics.StackTrace class

Hope that you got my idea, and that helps and answers your question.

I didn't find this answer anywhere in the internet, I thought about this idea by myself using my brain.

I will answer only "How" question.

There are so many answers here, however I would like to propose kind of "design pattern" to achieve that feature. I will use simple language mechanism, which includes:

  • इंटरफेस
  • Nested class

For example we have 2 main classes: Student and University. Student has GPA which only university allowed to access. यहां कोड है:

 public interface IStudentFriend { Student Stu { get; set; } double GetGPS(); } public class Student { // this is private member that I expose to friend only double GPS { get; set; } public string Name { get; set; } PrivateData privateData; public Student(string name, double gps) { GPS = gps; Name = name; privateData = new PrivateData(this); } // No one can instantiate this class, but Student // Calling it is possible via the IStudentFriend interface class PrivateData : IStudentFriend { public Student Stu { get; set; } public PrivateData(Student stu) { Stu = stu; } public double GetGPS() { return Stu.GPS; } } // This is how I "mark" who is Students "friend" public void RegisterFriend(University friend) { friend.Register(privateData); } } public class University { List<IStudentFriend> studentsFriends = new List<IStudentFriend>(); public void Register(IStudentFriend friendMethod) { studentsFriends.Add(friendMethod); } public void PrintAllStudentsGPS() { foreach (var stu in studentsFriends) { Console.WriteLine(stu.Stu.Name + ": " + stu.GetGPS()); } } } static void Main(string[] args) { University Technion = new University(); Student Alex = new Student("Alex", 98); Alex.RegisterFriend(Technion); Student Jo = new Student("Jo", 91); Jo.RegisterFriend(Technion); Technion.PrintAllStudentsGPS(); Console.ReadLine(); }