2012-12-19 9 views
10

क्या हम सार्वजनिक रूप से दिखाई देने वाली कक्षा की संपत्ति बना सकते हैं, लेकिन केवल कुछ विशिष्ट वर्गों द्वारा संशोधित किया जा सकता है?सी # में चुनिंदा संपत्ति-दृश्यता को कैसे कार्यान्वित करें?

उदाहरण के लिए

,

// this is the property holder 
public class Child 
{ 
    public bool IsBeaten { get; set;} 
} 

// this is the modifier which can set the property of Child instance 
public class Father 
{ 
    public void BeatChild(Child c) 
    { 
     c.IsBeaten = true; // should be no exception 
    } 
} 

// this is the observer which can get the property but cannot set. 
public class Cat 
{ 
    // I want this method always return false. 
    public bool TryBeatChild(Child c) 
    { 
     try 
     { 
      c.IsBeaten = true; 
      return true; 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 

    // shoud be ok 
    public void WatchChild(Child c) 
    { 
     if(c.IsBeaten) 
     { 
      this.Laugh(); 
     } 
    } 

    private void Laugh(){} 
} 

बाल एक डेटा वर्ग है,
जनक एक वर्ग है कि डेटा को संशोधित कर सकते हैं,
बिल्ली एक वर्ग है कि केवल डेटा को पढ़ सकता है।

क्या संपत्ति में सी # का उपयोग करके इस तरह के अभिगम नियंत्रण को लागू करने का कोई तरीका है?

उत्तर

4

बल्कि बाल वर्ग के भीतर राज्य को उजागर से आप के बजाय एक विधि प्रदान कर सकता है:

class Child { 
    public bool IsBeaten { get; private set; } 

    public void Beat(Father beater) { 
    IsBeaten = true; 
    } 
} 

class Father { 
    public void BeatChild(Child child) { 
    child.Beat(this); 
    } 
} 

तो बिल्ली अपने बच्चे को नहीं हरा सकते हैं:

class Cat { 
    public void BeatChild(Child child) { 
    child.Beat(this); // Does not compile! 
    } 
} 

अन्य लोगों के लिए की जरूरत है

interface IChildBeater { } 

फिर उन्हें लागू किया है: बच्चे को हरा, एक अंतरफलक वे लागू कर सकते हैं परिभाषित सक्षम हो यह:

class Child { 
    public bool IsBeaten { get; private set; } 

    public void Beat(IChildBeater beater) { 
    IsBeaten = true; 
    } 
} 

class Mother : IChildBeater { ... } 

class Father : IChildBeater { ... } 

class BullyFromDownTheStreet : IChildBeater { ... } 
+0

thx। लेकिन क्या होगा यदि हम _Beater_ को परिभाषित या परिवर्तित नहीं कर सकते? यानी, _Child_ कोड क्लाइंट कोड है, जबकि _Beater_ एक तृतीय-पक्ष पैकेज हो सकता है जो कुछ कार्यों को क्रमबद्ध करता है और बाद में किसी अन्य उदार द्वारा प्रतिस्थापित किया जा सकता है? – lowatt

+0

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

2

यह आमतौर पर अलग असेंबली और InternalsVisibleToAttribute का उपयोग करके हासिल किया जाता है। जब आप set को वर्तमान असेंबली के भीतर internal कक्षाओं के साथ चिह्नित करेंगे, तो इसका उपयोग होगा। उस विशेषता का उपयोग करके, आप विशिष्ट अन्य असेंबली तक पहुंच सकते हैं। प्रतिबिंब का उपयोग करके याद रखें यह अभी भी संपादन योग्य होगा।

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