2013-05-15 10 views
14

द्वारा कहा जा रहा एक कक्षा में एक विशेष विधि केवल एक विशेष वर्ग द्वारा सुलभ होना चाहता हूँ। उदाहरण के लिए:सीमा विधि केवल एक विशेष वर्ग

public class A 
{ 
    public void LimitedAccess() {} 
    public void FullAccess() {} 
} 

public class B 
{ 
    public void Func() 
    { 
    A a = new A(); 
    a.LimitedAccess();  // want to be able to call this only from class B 
    } 
} 

public class C 
{ 
    public void Func() 
    { 
    A a = new A(); 
    a.FullAccess();   // want to be able to call this method 
    a.LimitedAccess();  // but want this to fail compile 
    } 
} 

क्या कोई ऐसा कीवर्ड या विशेषता है जिसका उपयोग मैं इसे लागू करने के लिए कर सकता हूं?

अद्यतन: कारण मौजूदा प्रणाली जटिलता और समय की कमी के

, मैं एक कम प्रभाव समाधान की जरूरत है। और मैं कुछ संकलित समय पर इंगित करना चाहता था कि LimitedAccess() का उपयोग नहीं किया जा सका। मुझे जॉन स्कीट के जवाब पर भरोसा है कि मैंने जो कुछ पूछा था वह सी # में नहीं किया जा सका।

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

एक टिप्पणी में उल्लेख किया है, C# friend बातचीत उपयोगी पढ़ने अगर आप एक ऐसी ही स्थिति को सुलझाने की कोशिश कर रहे हैं।

मेरी विशेष समाधान के लिए के रूप में: "क्यों एक बी के तर्क होता हैं," (टिप्पणी में @sysexpand द्वारा पूछे जाने पर)। वह रगड़ है। B.Func() को पूरे सिस्टम में बुलाया गया था जिस पर मैं काम कर रहा हूं, लेकिन यह मुख्य रूप से A के सिंगलटन पर संचालित होता है। तो मैं क्या कर रहा था BFunc()A में A.LimitedAccess() निजी बना रहा था। आसपास के काम करने के लिए कुछ अन्य विवरण थे, जैसा कि हमेशा होता है, लेकिन मुझे कम प्रभाव समाधान मिला जिसने मुझे कॉलर्स पर A.LimitedAccess() पर संकलन-समय त्रुटियां दीं।

चर्चा के लिए धन्यवाद।

+0

आप ऐसा क्यों करना चाहते हैं? –

+0

मेरे पास एक बड़ी कक्षा 'ए' है जिसका उपयोग पूरे सिस्टम में बड़े पैमाने पर किया जाता है। कक्षा 'बी 'में अन्य निर्भरताएं हैं लेकिन बीएलमिटेडएप() का उपयोग करने का मानक/सर्वोत्तम तरीका है। जब भी संभव हो मैं 'B.Func()' का उपयोग करके लागू करना चाहता हूं। – jltrem

+0

देखें http://stackoverflow.com/questions/203616/why-does-c-sharp-not-provide-the-c-style-friend-keyword आपको 'LimitedAccess' को आंतरिक के रूप में चिह्नित करना चाहिए और कोड के माध्यम से इसका दुरुपयोग करना चाहिए समीक्षा। – Yaur

उत्तर

18

नहीं। केवल एक चीज जो आप कर सकते हैं LimitedAccess एक निजी विधि, और घोंसला वर्ग B कक्षा A के भीतर बनाना होगा।

(मैं आप एक ही विधानसभा में सभी वर्गों चाहते संभालने हूँ। नहीं तो आप एक अलग विधानसभा में A और एक ही विधानसभा में B, और C डाल सकता है, और LimitedAccess एक internal विधि बना दें।)

+2

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

0

यह ऐसे डिजाइन करने के लिए ओओपी सर्वोत्तम प्रथाओं के खिलाफ है। कक्षाओं के तरीके को बुलाए जाने से संरक्षित नहीं किया जाना चाहिए।

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

+1

जॉन ने ऐसा करने के दो पूरी तरह से उपयुक्त साधन प्रदान किए हैं। दूसरी ओर, आपकी विधि, इस बारे में जाने का बिल्कुल गलत तरीका है। आपको कोई संकलन समय समर्थन नहीं मिलता है, इसे आसानी से एक डिकंपेलर के उपयोग के माध्यम से तोड़ दिया जाता है या हैक किया जाता है, और कक्षा के उपयोगकर्ताओं को अब यह देखने के लिए एक भ्रमित API विधि है कि वे वास्तव में उपयोग नहीं करना चाहते हैं। – Servy

+0

सवाल यह था: "मैं एक वर्ग में एक विशेष विधि केवल एक विशेष वर्ग द्वारा पहुंच योग्य होना चाहता हूं।" आप बस ऐसा करने की कोशिश नहीं करते ... दूसरी बात यह है कि एक विधि आंतरिक घोषित करें और फिर इसे असेंबली में सभी वर्गों से एक्सेस करें। लेकिन वह सवाल नहीं था। –

+0

और यह उस समस्या को हल नहीं करता है; विधि अभी भी हर जगह सुलभ हो जाएगी, अगर सही जादू तर्क के बिना कहीं भी उपयोग किया जाता है तो यह ठीक से काम नहीं करेगा। जॉन के दोनों समाधानों में वास्तव में उन तरीकों की पहुंच को सीमित करना शामिल है, जिनके पास पहुंच नहीं होनी चाहिए। – Servy

2

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

public interface IA 
{ 
    void FullAccess(); 
} 


public class A 
{ 
    public void LimitedAccess() {} //does not implement any interface 
    public void FullAccess() {}  //implements interface 
} 


public class B 
{ 
    private A a = new A(); 

    public IA GetA() 
    { 
    return (IA)a; 
    } 

    public void Func() 
    { 
    /* will be able to call LimitedAccess only from class B, 
     as long as everybody else only has a reference to the interface (IA). */ 
    a.LimitedAccess();  
    } 
} 


//This represents all other classes 
public class C 
{ 
    public IA Ia; 

    public void Func() 
    { 
    Ia.FullAccess();   // will be able to call this method 
    Ia.LimitedAccess();  // this will fail compile 
    } 
} 

public static class MainClass 
{ 
    static void Main(string[] args) 
    { 
    B b = new B(); 
    b.func(); 
    C c = new C(); 
    c.Ia = b.GetA(); 
    c.func(); 
    } 
} 
0

शायद यह एक कामकाज है।

System.Runtime.CompilerServices का प्रयोग करें और फिर आप बुला समारोह और/या फ़ाइल है, जो में बुला समारोह परिभाषित किया गया है का नाम जांच कर सकते हैं या तो। यदि आपके पास प्रति फ़ाइल एक वर्ग है, तो फ़ाइल नाम कक्षा के नाम के लिए एक औसत हो सकता है। इसे जांचें और कॉल को अवरुद्ध करें।

internal void MySecretFunction (string something, 
    [CallerMemberName] string memberName = null, 
    [CallerFilePath] string filePath = null, 
    [CallerLineNumber] int lineNumber = 0) { 
    if (!filePath.EndsWith(@"\goodClass.cs")) return; 

    // else do something 
} 
संबंधित मुद्दे