2010-09-26 22 views
7

मैंने एक कक्षा लिखी है जो IEnumerable<T> लागू करती है। मेरे पास एक विधि है जो MyClass लौटाती है। अगर मैं उस विधि के भीतर से yield return करने का प्रयास करता हूं, तो संकलक मुझे बताता है "... एक इटरेटर ब्लॉक नहीं हो सकता है क्योंकि ... एक इटरेटर इंटरफ़ेस प्रकार नहीं है"।एक इटरेटर इंटरफ़ेस प्रकार को परिभाषित करने के लिए कैसे?

तो, मैं अपना इंटरफ़ेस इटरेटर प्रकार कैसे परिभाषित कर सकता हूं? क्या इसे "अमूर्त" होना चाहिए (क्या कोई तरीका परिभाषित नहीं किया जा सकता है)?

मैं जो करना चाहता हूं वह श्रृंखला योग्य तरीकों का एक समूह लिखना है, इसलिए प्रत्येक विधि को MyClass का उदाहरण वापस करना चाहिए। लेकिन मुझे किसी प्रकार की गणना करने के लिए MyClass की आवश्यकता है। कुछ अंतर्निहित डेटा प्रकार का उपयोग करने के बजाय, मैं उम्मीद कर रहा था कि मैं हर जगह yield return कर सकता हूं।


@Oded:

class SharpQuery : IEnumerable<HtmlNode> 
{ 
    public SharpQuery Find(string selector) 
    { 
     foreach (var n in this) 
     { 
      // filter the results 
      yield return node; 
     } 
    } 
} 
+1

क्या आप अपने कोड के प्रासंगिक बिट पोस्ट कर सकते हैं? – Oded

उत्तर

10

नहीं, यह नहीं हो सकता है। यह देखने के लिए कि क्यों मानते हैं कि आपके पास Zoo है जो IEnumerable<Animal> लागू करता है लेकिन इसमें कई अन्य सदस्य भी हैं। एक Zoo एक IEnumerable<Animal> है लेकिन आवश्यक रूप से इसके विपरीत नहीं - जानवरों का अनुक्रम जानवरों का एक अनुक्रम है। कोई चिड़ियाघर कीपर नहीं है, कोई दुकान नहीं, कोई प्रवेश शुल्क नहीं है या कोई अन्य चीज है जो चिड़ियाघर को चिड़ियाघर बनाती है।

जब आप yield return x का उपयोग करते हैं तो वापसी प्रकार Zoo नहीं हो सकता है क्योंकि आपके पास चिड़ियाघर नहीं है - आपके पास जानवरों का अनुक्रम है।

क्या आप के बजाय कर सकते हैं जहां foo रिटर्न एक IEnumerable<Animal>new Zoo(foo()) के रूप में यह फोन और Zoo कि एक IEnumerable<Animal> स्वीकार करता है करने के लिए एक निर्माता जोड़ना है।

+0

भले ही 'चिड़ियाघर' में कोई डेटा न हो, बस विधियां? – mpen

+2

यदि आपके पास केवल विधियां हैं तो आप उन्हें 'IENumerable ' पर एक्सटेंशन विधियों के रूप में लागू कर सकते हैं। तब मुझे लगता है कि आप जो चाहते थे उसे प्राप्त करें - आप आसानी से उपज का उपयोग कर सकते हैं, और आप अपने अनुक्रमों पर विशेष तरीकों का उपयोग कर सकते हैं। –

+0

मुझे एक कन्स्ट्रक्टर की आवश्यकता है हालांकि ... मुझे लगता है कि केवल एक आइटम उत्पन्न होगा। तो मुझे लगता है कि मैं इसके बजाय इसके लिए एक सार्वजनिक समारोह का उपयोग कर सकता हूं। मुझे इसके बारे में कुछ और सोचना है ... अगर मैं वास्तव में खुद को एक स्टेटलेस क्लास में बाध्य करना चाहता हूं ... हालांकि यह एक साफ विचार है। धन्यवाद! – mpen

2

मुझे लगता है कि जब आप yield return x का उपयोग करते हैं तो आप एक्स प्रकार के IEnumerable का उत्पादन करेंगे। तो आपके मामले में यह IENumerable

एक वर्ग से विरासत का स्वचालित रूप से यह अर्थ नहीं होगा कि यह निश्चित रूप से उस प्रकार के लिए स्वयं को डालेगा। तो यदि आप

class SharpQuery 
{ 
    public IEnumerable<HtmlNode> RepositoryItems { get; set; } 
    public IEnumerable<HtmlNode> Find(string selector) 
    { 
     foreach (var n in this.RepositoryItems) 
     { 
      // filter the results 
      yield return node; 
     } 
    } 
} 

लिखते हैं तो यह काम करता है। IENumerable SharpQuery के समान नहीं है।

+0

यह काम नहीं करता है क्योंकि HtmlNode परिभाषित नहीं किया गया है। – user1789573

+0

अच्छा पकड़ो। हाँ वास्तव में यह एक पट्टी संस्करण है। SharpQuery वास्तव में IENumerable लागू नहीं करता है, लेकिन खोज की वापसी काम करेगा। मैंने इसे ठीक कर दिया है। – abhishek

2

सी # भाषा विशिष्टता संस्करण 4.0 की धारा 8.2 के अनुसार:

एक ब्लॉक है कि एक या अधिक yield बयान शामिल पुनरावर्तक ब्लॉक कहा जाता है। इटरेटर ब्लॉक का उपयोग फ़ंक्शन सदस्यों को इटरेटर के रूप में कार्यान्वित करने के लिए किया जाता है।

धारा 10.14 निर्दिष्ट करता है कि पुनरावर्तक की वापसी प्रकार निम्न में से एक होना चाहिए:

  • IEnumerator
  • IEnumerable
  • IEnumerator<T>
  • IEnumerable<T>

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

  • IEnumerator
  • IEnumerator<T>
  • IDisposable

प्रगणक वस्तु आम तौर पर एक संकलक उत्पन्न नेस्टेड वर्ग का एक उदाहरण है निजी पहुंच के साथ।

+0

मुझे लगता है कि मैं कुछ ऐसा वापस करना चाहता था जो इंटरफ़ेस की बजाय उन इंटरफ़ेस में से एक को लागू करता था। – mpen

+0

प्रति https://msdn.microsoft.com/en-us/library/ms228593.aspx सी # spec 'प्रोग्राम फ़ाइलें (x86)/माइक्रोसॉफ्ट विजुअल स्टूडियो 12.0/वीसी #/विनिर्देशों/1033' में विजुअल स्टूडियो के साथ स्थापित किया गया है। दृश्य स्टूडियो संस्करण को उपयुक्त के रूप में बदलें, वीएस2015 के लिए 14.0, इत्यादि – BurnsBA

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

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