2013-07-15 7 views
5
  1. मैं IEnumerable < टी []> एक सामान्य वर्ग एक < टी>, को लागू करने वाली है।
  2. मैं एक सुविधा आवरण बी कि एक < चार से इनहेरिट करना चाहते हैं> और IEnumerable < स्ट्रिंग> लागू करता है।एकाधिक IEnumerable कार्यान्वयन विरोधाभास

    public class A<T> : IEnumerable<T[]> 
    { 
        public IEnumerator<T[]> GetEnumerator() 
        { 
         return Enumerate().GetEnumerator(); 
        } 
    
        IEnumerator IEnumerable.GetEnumerator() 
        { 
         return GetEnumerator(); 
        } 
    
        protected IEnumerable<T[]> Enumerate() 
        { 
         throw new System.NotImplementedException(); 
        } 
    } 
    
    public class B : A<char>, IEnumerable<string> 
    { 
        public IEnumerator<string> GetEnumerator() 
        { 
         return Enumerate().Select(s => new string(s)).GetEnumerator(); 
        } 
    
        IEnumerator IEnumerable.GetEnumerator() 
        { 
         return GetEnumerator(); 
        } 
    } 
    

अब, यह पूरी तरह से ठीक काम करता है, वैरिएबल प्रकार foreach स्ट्रिंग होने के लिए मान लिया जाता है:

B b = new B(); 
foreach (var s in b) 
{ 
    string[] split = s.Split(' '); 
} 

लेकिन इस संकलन नहीं होगा, कि "प्रकार तर्क के उपयोग से नहीं लगाया जा सकता , "स्पष्ट रूप से प्रकार तर्क निर्दिष्ट करने का प्रयास:

string[] strings = b.ToArray(); 

बहरहाल, यह काम करता है:

string[] strings = b.ToArray<string>(); 

क्या कोई इस कंपाइलर व्यवहार को समझा सकता है?

जाहिर है, बी लागू करता है दोनों IEnumerable < चार []> और IEnumerable < स्ट्रिंग> और शायद इसे समझ नहीं जो उनमें से मैं कॉल करना चाहते हैं, लेकिन क्यों यह "foreach" नमूने में ठीक काम करता है ?

कृपया, मुझे रचना द्वारा मेरी समस्या को हल करने का सुझाव न दें - यह मेरे लिए आखिरी उपाय है।

उत्तर

2

अंतर निम्नलिखित है। यह वास्तव में IEnumerable<T> की परवाह नहीं करता है। आपकी कक्षा B में केवल GetEnumerator नामक एक सार्वजनिक विधि है: B में परिभाषित एक जो छुपाता है जिसे A में परिभाषित किया गया है।

ToArray दूसरी तरफ IEnumerable<T> पर एक विस्तार विधि है। चूंकि आपकी कक्षा IEnumerable<string> और IEnumerable<char[]> दोनों कॉल सामान्य जेनेरिक तर्क string और char[] के बीच संदिग्ध है।

2

foreach लूप IEnumerable या IEnumerable<T> कार्यान्वयन का उपयोग नहीं करता है। आप foreach का उपयोग कर सकते हैं भले ही आपकी कक्षा उनमें से कोई भी लागू न करे। इसकी आवश्यकता केवल एक चीज है GetEnumerator विधि जो IEnumerator कार्यान्वयन देता है।

चेक इस सवाल: How is foreach implemented in C#?

यही कारण है कि अपने वर्ग foreach साथ काम करता है और ToArray() साथ ऐसा नहीं करता है।

foreach वास्तव में एक सार्वजनिक विधि GetEnumerator कहा जाता है के लिए लग रहा है:

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