2008-10-15 15 views
145

संभव डुप्लिकेट:
Why does C# not provide the C++ style ‘friend’ keyword?दोस्त के सी # समतुल्य क्या है?

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

सी ++ में मैं सिर्फ टेस्टर क्लास को दोस्त के रूप में घोषित करता हूं, मैं इसे सी # में कैसे कर सकता हूं? क्या कोई मुझे एक उदाहरण दे सकता है?

+2

आपको निजी सदस्यों का सीधे परीक्षण नहीं करना चाहिए जैसे कि वे सार्वजनिक रूप से सुलभ हों। आम तौर पर, लोग केवल सार्वजनिक सदस्यों के खिलाफ परीक्षण करते हैं: http://stackoverflow.com/a/5662371/62921 निजी सदस्यों का अप्रत्यक्ष तरीके से परीक्षण किया जाएगा। मुझे कुछ नया सिखाने के लिए – ForceMagic

उत्तर

213

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

उदाहरण: में AssemblyInfo.cs

[assembly: InternalsVisibleTo("OtherAssembly")] 
+20

+1। – Brian

+7

दिलचस्प नोट, वीबीएनईटी 'आंतरिक' में अभी भी 'मित्र' कहा जाता है। – Jeff

+1

एमएसडीएन कहता है: "एक असेंबली में सभी गैर-सार्वजनिक प्रकार किसी अन्य असेंबली के लिए दृश्यमान होते हैं" कितना बदसूरत! कभी भी उस बकवास का उपयोग कौन करेगा? मैं रॉब से जवाब पसंद करता हूं। – Elmue

13

वहाँ सी # में एक 'मित्र' कीवर्ड लेकिन निजी तरीकों के परीक्षण के लिए एक ही विकल्प System.Reflection का उपयोग करने के लिए एक संभाल पाने के लिए नहीं है रखा जाना करने के लिए तरीका। यह आपको निजी तरीकों का आह्वान करने की अनुमति देगा।

public class Class1 
{ 
    private int CallMe() 
    { 
     return 1; 
    } 
} 

आप इस कोड का उपयोग यह आह्वान कर सकते हैं:

इस परिभाषा के साथ एक वर्ग को देखते हुए

Class1 c = new Class1(); 
Type class1Type = c.GetType(); 
MethodInfo callMeMethod = class1Type.GetMethod("CallMe", BindingFlags.Instance | BindingFlags.NonPublic); 

int result = (int)callMeMethod.Invoke(c, null); 

Console.WriteLine(result); 

आप विजुअल स्टूडियो टीम सिस्टम का उपयोग कर रहे हैं तो आप वी.एस. स्वचालित रूप से एक उत्पन्न करने के लिए प्राप्त कर सकते हैं विधि पर दायाँ क्लिक करके और "यूनिट टेस्ट बनाएं ..." का चयन करके निजी एक्सेसर्स के साथ प्रॉक्सी क्लास

+0

प्रतिबिंब में भारी प्रदर्शन लागत है और अक्सर खराब पठनीय कोड की ओर जाता है। जब यह विकल्प होता है तो "आंशिक बाहरी वर्ग" दृष्टिकोण मेरे लिए बहुत बेहतर होता है। – AFract

35

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

सी ++ में, फैक्ट्री को विजेट क्लास का मित्र बनाएं।

सी # में, हम क्या कर सकते हैं? मेरे साथ हुआ एकमात्र सभ्य समाधान एक इंटरफ़ेस का आविष्कार करना है, IWidget, जो केवल सार्वजनिक तरीकों का खुलासा करता है, और फैक्टरी रिटर्न IWidget इंटरफेस है।

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

52

कोठरी समकक्ष एक घोंसला वर्ग बनाना है जो बाहरी वर्ग के निजी सदस्यों तक पहुंचने में सक्षम होगा। कुछ इस तरह:

class Outer 
{ 
    class Inner 
    { 
     // This class can access Outer's private members 
    } 
} 

या यदि आप किसी अन्य फाइल में इनर वर्ग डाल करने के लिए पसंद करते हैं:

Outer.cs 
partial class Outer 
{ 
} 


Inner.cs 
partial class Outer 
{ 
    class Inner 
    { 
     // This class can access Outer's private members 
    } 
} 
+6

ध्यान दें कि बाहरी वर्ग के सदस्यों तक पहुंचने के लिए, जब तक वेरिएबल स्थैतिक (या कॉन्स्ट) नहीं है, तब भी आपको बाहरी के उदाहरण के संदर्भ की आवश्यकता है। यहां स्वीकृत उत्तर के अनुसार: http://stackoverflow.com/questions/3155172/inner-class-and-outer-class-in-c-sharp – Itison

+0

मुझे आश्चर्य है कि क्या आप 'इनर' कक्षा के लिए एक्सटेंशन विधियों का उपयोग कर सकते हैं। मैं इसे आजमाने की कोशिश कर रहा हूँ! :) – Jess

+2

दोह! एक आंतरिक कक्षा पर विस्तार विधियों की अनुमति नहीं है। – Jess

6

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

// Expose the internal members to the types in the My.Tester assembly 
[assembly: InternalsVisibleTo("My.Tester, PublicKey=" + 
"012700000480000094000000060200000024000052534131000400000100010091ab9" + 
"ba23e07d4fb7404041ec4d81193cfa9d661e0e24bd2c03182e0e7fc75b265a092a3f8" + 
"52c672895e55b95611684ea090e787497b0d11b902b1eccd9bc9ea3c9a56740ecda8e" + 
"961c93c3960136eefcdf106955a4eb8fff2a97f66049cd0228854b24709c0c945b499" + 
"413d29a2801a39d4c4c30bab653ebc8bf604f5840c88")] 

आपकी आवश्यकताओं के आधार पर सार्वजनिक कुंजी वैकल्पिक है।

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