2012-05-19 14 views
5

ठीक है, मैं यही करना चाहता हूं।इंटरफेस में स्वयं संदर्भ

Class Container<T> 
{ 
    T contained; 
    public void ContainObject(T obj) 
    { 
     contained = obj; 
     if(/*Magical Code That Detects If T Implemtns IContainableObject*/) 
     { 
      IContainableObect c = (IContainableObject)obj; 
      c.NotifyContained(self); 
     } 
    } 
} 

interface IContainableObject 
{ 
    public void NotifyContained(Container<REPLACE_THIS>);//This line is important, see below after reading code. 
} 



Class ImplementingType : IContaiableObject 
{ 
    public Container<ImplementingType> MyContainer; 
    public void NotifyContained(Container<ImplmentingType> c) 
    { 
     MyContainer = c; 
    } 
} 




Class Main 
{ 
    public static void Main(args) 
    { 
     ImplementingType iObj = new ImplementingType(); 
     Container<ImplementingType> container = new Container(); 
     container.ContainObject(iObj); 
     //iObj.MyContainer should now be pointing to container. 
    } 
} 

मूल रूप से, ऊपर के उदाहरण योग करने के लिए, मैं प्रकार टी की एक सामान्य आवरण प्रकार है मुझे लगता है कि आवरण प्रकार चाहते हैं सूचित करने के लिए जो कुछ भी यह है कि यह निहित किया जा रहा है शामिल हैं (अपनी स्वयं की एक प्रति के साथ !) यदि निहित वस्तु एक विशिष्ट इंटरफ़ेस लागू करती है (यह बिट मुझे पता है कि कैसे करें)

लेकिन यह मुश्किल हो जाता है! क्यूं कर? खैर क्योंकि कंटेनर जेनेरिक को एक प्रकार की आवश्यकता है।

महत्वपूर्ण लाइन याद रखें?

यदि REPLACE_THIS IContainableObject है, तो इंटरफ़ेस के सभी कार्यान्वयनकर्ताओं को आईसीओन्टैनर ऑब्जेक्ट का उपयोग करना चाहिए, न कि उनके NotifyContained विधि में कार्यान्वयन वर्ग का नाम।

इंटरफेस के भीतर कंटेनर के प्रकार के रूप में कार्यान्वयन प्रकार का उपयोग करना स्पष्ट कारणों से भी बदतर है!

तो मेरा सवाल यह है कि, मैं REPLACE_THIS इंटरफ़ेस को लागू करने वाले ऑब्जेक्ट की कक्षा का प्रतिनिधित्व करने के लिए क्या करूँ?

उत्तर

4
class Container<T> 
{ 
    T contained; 
    public void ContainObject(T obj) 
    { 
     contained = obj; 
     var containable = obj as IContainableObject<T>; 
     if(containable != null) 
     { 
      containable.NotifyContained(this); 
     } 
    } 
} 

interface IContainableObject<T> 
{ 
    void NotifyContained(Container<T> c); 
} 

class ImplementingType : IContainableObject<ImplementingType> 
{ 
    public Container<ImplementingType> MyContainer; 
    public void NotifyContained(Container<ImplementingType> c) 
    { 
     MyContainer = c; 
    } 
} 

संपादित करें: सामान्य बाधा

interface IContainer<T> 
{ 
    void ContainObject(T obj); 
} 

class Container<T> : IContainer<T> where T : IContainableObject<T> 
{ 
    T contained; 

    public void ContainObject(T obj) 
    { 
     contained = obj; 
     contained.NotifyContained(this); 
    } 
} 

interface IContainableObject<T> 
{ 
    void NotifyContained(IContainer<T> c); 
} 

class ImplementingType : IContainableObject<ImplementingType> 
{ 
    public IContainer<ImplementingType> MyContainer; 

    public void NotifyContained(IContainer<ImplementingType> c) 
    { 
     Debug.WriteLine("notify contained"); 
     MyContainer = c; 
    } 
} 
+0

की तरह अपने वर्ग घोषणा कर सकते हैं धन्यवाद बहुत ज्यादा! एक आकर्षण की तरह काम करता है :) –

+1

यदि आप टी –

+0

के लिए सामान्य बाधा घोषित करते हैं तो आप कास्टिंग से बच सकते हैं ओप्स मैंने आईसीओन्टैनर ऑब्जेक्ट के लिए एक खाली इंटरफ़ेस बनाया है - मैंने आकस्मिक रूप से टाइप किए गए आईसीओन्टैनर को आईकॉन्टेनेबल नहीं देखा है, इसके बाद मैंने अपने उदाहरण कोड में एक टाइपो देखा है। क्या इसका मतलब है कि आपके आईकॉन्टेनर इंटरफेस को हटाया जा सकता है? –

1

शायद तुम यह पहले से ही पता है के साथ संस्करण जोड़ने, लेकिन अगर केवल IContainableObjectsT के रूप में अनुमति दी जाती है तो आप इस

class Container<T> 
    where T : IContainableObject 
{ 
    public void ContainObject(T obj) 
    { 
     // Here you know that obj does always implement IContainableObject. 
     obj.NotifyContained(this); 
    } 

    ... 
} 
+0

दिलचस्प समाधान! IContainableObject एक वैकल्पिक इंटरफ़ेस है - केवल उन लोगों के लिए जो इसे चाहते हैं, इसलिए यह मेरे लिए एक व्यवहार्य विकल्प नहीं है, लेकिन किसी भी अन्य मामले में ऐसा लगता है कि यह काम करेगा :) –

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