एक IEnumerable <T> से आइटम्स की गणना करें?


317
private IEnumerable<string> Tables
{
    get
    {
        yield return "Foo";
        yield return "Bar";
    }
}

मान लीजिए कि मैं उन पर पुनरावृति चाहता हूं और # एम के # प्रसंस्करण की तरह कुछ लिखता हूं।

क्या कोई ऐसा तरीका है जिससे मैं अपने मुख्य पुनरावृत्ति से पहले पुनरावृत्ति के बिना मी का मूल्य ज्ञात कर सकता हूँ?

मुझे उम्मीद है कि मैंने खुद को स्पष्ट कर दिया है।

जवाबों:


338

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

यदि आप उन वस्तुओं की संख्या जानना चाहते हैं, जिन्हें आप उपयोग नहीं कर सकते हैं ICollection<T>, तो इसके पास एक Countसंपत्ति है।


38
यदि आप अनुक्रमणिका द्वारा सूची तक पहुँचने की आवश्यकता नहीं है, तो मैं IList पर ICollection का पक्ष लूंगा।
माइकल मीडोज

3
मैं आमतौर पर सूची और IList को आदत से बाहर निकालता हूं। लेकिन विशेष रूप से यदि आप उन्हें स्वयं लागू करना चाहते हैं तो ICollection आसान है और काउंट संपत्ति भी है। धन्यवाद!
Mendelt

21
@ शमी आप तत्वों की पुनरावृति और गणना करते हैं। या आप Linq नामस्थान से गणना () कहते हैं जो आपके लिए ऐसा करती है।
मेंडेल

1
बस ILn के साथ IEnumerable की जगह सामान्य परिस्थितियों में पर्याप्त होना चाहिए?
टेकेन

1
@ हेल्गी क्योंकि IEnumerable का मूल्यांकन किया जाता है lazily आप इसे उन चीजों के लिए उपयोग कर सकते हैं जिनका उपयोग IList नहीं किया जा सकता है। आप एक फ़ंक्शन का निर्माण कर सकते हैं जो एक IEnumerable देता है जो उदाहरण के लिए Pi के सभी दशमलव को शामिल करता है। जब तक आप कभी भी पूरा नतीजा निकालने की कोशिश नहीं करते, तब तक यह काम करना चाहिए। आप एक IList युक्त Pi नहीं बना सकते। लेकिन यह सब बहुत अकादमिक है। अधिकांश सामान्य उपयोगों के लिए मैं पूरी तरह से सहमत हूं। यदि आपको गणना की आवश्यकता है तो आपको IList की आवश्यकता है। :-)
Mendelt

215

System.Linq.Enumerable.Countविस्तार पद्धति पर IEnumerable<T>निम्नलिखित कार्यान्वयन है:

ICollection<T> c = source as ICollection<TSource>;
if (c != null)
    return c.Count;

int result = 0;
using (IEnumerator<T> enumerator = source.GetEnumerator())
{
    while (enumerator.MoveNext())
        result++;
}
return result;

तो यह कास्ट करने की कोशिश करता है ICollection<T>, जिसके पास एक Countसंपत्ति है, और यदि संभव हो तो इसका उपयोग करता है। अन्यथा यह पुनरावृति करता है।

तो आपकी सबसे अच्छी शर्त यह है कि आप Count()अपने IEnumerable<T>ऑब्जेक्ट पर एक्सटेंशन विधि का उपयोग करें , क्योंकि आपको उस तरह से सबसे अच्छा प्रदर्शन संभव होगा।


13
बहुत दिलचस्प बात यह है कि यह ICollection<T>पहली बार कास्ट करने की कोशिश करता है ।
बजे ऑस्कर मेडेरोस

1
@OcarMederos Enumerable में अधिकांश विस्तार विधियों में विभिन्न प्रकारों के अनुक्रमों के लिए अनुकूलन होते हैं, जहां वे यदि चाहें तो सस्ते तरीके का उपयोग करेंगे।
शिबूमी

1
उल्लिखित विस्तार .net 3.5 और MSDN में प्रलेखित होने के बाद से उपलब्ध है ।
ईसाई

मुझे लगता है कि आप सामान्य प्रकार की जरूरत नहीं है Tपर IEnumerator<T> enumerator = source.GetEnumerator(), बस आप यह कर सकते हैं: IEnumerator enumerator = source.GetEnumerator()और काम करना चाहिए!
जैदर

7
@ जैदर - यह उससे थोड़ा अधिक जटिल है। IEnumerable<T>इनहेरिट करता है IDisposableजो usingस्टेटमेंट को स्वचालित रूप से डिस्पोज करने की अनुमति देता है । IEnumerableनहीं करता। इसलिए यदि आप GetEnumeratorकिसी भी तरह से कॉल करते हैं, तो आपको खत्म करना चाहिएvar d = e as IDisposable; if (d != null) d.Dispose();
डैनियल ईयरविकेर

87

बस अतिरिक्त कुछ जानकारी जोड़ना:

Count()विस्तार हमेशा पुनरावृति नहीं है। Linq को Sql पर विचार करें, जहां गिनती डेटाबेस में जाती है, लेकिन सभी पंक्तियों को वापस लाने के बजाय, यह Sql Count()कमांड जारी करता है और इसके बजाय उस परिणाम को लौटाता है।

इसके अतिरिक्त, कंपाइलर (या रनटाइम) पर्याप्त स्मार्ट है कि यह ऑब्जेक्ट Count()विधि को कॉल करेगा यदि इसमें एक है। तो यह अन्य उत्तरदाताओं के रूप में नहीं है , तत्वों की गणना करने के लिए पूरी तरह से अनभिज्ञ और हमेशा पुनरावृत्त होना।

कई मामलों में जहां प्रोग्रामर एक्सटेंशन विधि if( enumerable.Count != 0 )का उपयोग करके जांच कर रहा है Any(), जैसा कि if( enumerable.Any() ) लाइनक के आलसी मूल्यांकन के साथ कहीं अधिक कुशल है क्योंकि यह शॉर्ट-सर्किट हो सकता है एक बार यह निर्धारित कर सकता है कि कोई तत्व हैं। यह अधिक पठनीय भी है


2
संग्रह और सरणियों के संबंध में। यदि आप संग्रह का उपयोग करते .Countहैं तो संपत्ति का उपयोग करें क्योंकि यह हमेशा जानता है कि यह आकार है। जब collection.Countकोई अतिरिक्त गणना नहीं की जाती है, तो यह पहले से ज्ञात संख्या को वापस कर देता है। Array.lengthजहाँ तक मुझे पता है, उसी के लिए । हालांकि, .Any()स्रोत के प्रगणक का उपयोग करके प्राप्त करता है using (IEnumerator<TSource> enumerator = source.GetEnumerator())और अगर यह कर सकता है तो सही रिटर्न देता है enumerator.MoveNext()। संग्रह के लिए:, if(collection.Count > 0)सरणियाँ: if(array.length > 0)और enumerables पर if(collection.Any())
नोप

1
पहला बिंदु कड़ाई से सच नहीं है ... LINQ to SQL इस एक्सटेंशन विधि का उपयोग करता है जो इस एक के समान नहीं है । यदि आप दूसरे का उपयोग करते हैं, तो गणना एक मेमोरी में की जाती है, एसक्यूएल फ़ंक्शन के रूप में नहीं
एलेक्सफॉक्सगिल

1
@AlexFoxGill सही है। यदि आप स्पष्ट रूप से अपने IQueryably<T>को कास्ट करते हैं तो IEnumerable<T>यह एक वर्ग गणना जारी नहीं करेगा। जब मैंने यह लिखा था, लिन्क टू सकेल नया था; मुझे लगता है कि मैं केवल उपयोग करने के लिए जोर दे रहा था Any()क्योंकि enumerables, संग्रह और sql के लिए यह बहुत अधिक कुशल और पठनीय (सामान्य रूप से) था। उत्तर में सुधार के लिए धन्यवाद।
रॉबर्ट पॉलसन

12

मेरे एक मित्र के पास ब्लॉग पोस्टों की एक श्रृंखला है जो इस बात का दृष्टांत प्रदान करती है कि आप ऐसा क्यों नहीं कर सकते। वह फ़ंक्शन बनाता है जो एक IEnumerable लौटाता है जहां प्रत्येक पुनरावृत्ति अगले अभाज्य संख्या, सभी तरह से देता है ulong.MaxValue, और अगले आइटम की गणना तब तक नहीं की जाती है जब तक आप इसके लिए नहीं पूछते हैं। त्वरित, पॉप प्रश्न: कितने आइटम वापस किए जाते हैं?

यहाँ पोस्ट हैं, लेकिन वे लंबे समय की तरह हैं:

  1. बियॉन्ड लूप्स (अन्य पदों में उपयोग किया जाने वाला प्रारंभिक गणना योग्य वर्ग प्रदान करता है)
  2. Iterate के आवेदन (प्रारंभिक कार्यान्वयन)
  3. पागल विस्तार के तरीके: ToLazyList (प्रदर्शन अनुकूलन)

2
मैं वास्तव में चाहता हूं कि एमएस ने प्रगणकों से यह पूछने का एक तरीका परिभाषित किया कि वे अपने बारे में क्या वर्णन कर सकते हैं ("कुछ भी नहीं जानने के साथ" एक वैध जवाब है)। किसी भी गणना करने वाले को "क्या आप अपने आप को परिमित होने के लिए जानते हैं" जैसे सवालों का जवाब देने में कोई कठिनाई नहीं होनी चाहिए, "क्या आप जानते हैं कि आप अपने आप को एन तत्वों से कम परिमित करते हैं", और "क्या आप अपने आप को अनंत जानते हैं", क्योंकि कोई भी गणना वैध रूप से हो सकती है। (यदि अनजाने में) उन सभी को "नहीं" का जवाब दें। अगर इस तरह के सवाल पूछने के लिए एक मानक साधन होता है, तो
एन्युमेरेटर्स के लिए

1
... (क्योंकि वे कह सकते हैं कि वे ऐसा करते हैं), और कोड के लिए यह मानकर कि एनुमरेटर जो अंतहीन अनुक्रमों को वापस करने का दावा नहीं करते हैं, बाध्य होने की संभावना है। ध्यान दें कि इस तरह के प्रश्न पूछने के साधन सहित (बॉयलरप्लेट को कम करने के लिए, संभवत: किसी संपत्ति को वापस करने के लिए एक EnumerableFeaturesवस्तु है) के लिए कुछ भी करने के लिए प्रगणकों की आवश्यकता नहीं होगी, लेकिन इस तरह के प्रश्न (जैसे कुछ अन्य लोगों के साथ पूछ सकते हैं) में सक्षम हो सकते हैं? हमेशा आइटम का एक ही क्रम वापस करें "," क्या आप सुरक्षित रूप से कोड के संपर्क में आ सकते हैं जो आपके अंतर्निहित संग्रह को नहीं बदलना चाहिए ", आदि) बहुत उपयोगी होगा।
सुपरकैट

यह बहुत अच्छा होगा, लेकिन मुझे अब यकीन है कि itter ब्लॉकों के साथ कितना अच्छा होगा। आपको किसी प्रकार के विशेष "उपज विकल्प" या कुछ और की आवश्यकता होगी। या शायद इट्रेटर विधि को सजाने के लिए विशेषताओं का उपयोग करें।
जोएल कोएहॉर्न

1
इटरेटर ब्लॉक किसी भी अन्य विशेष घोषणाओं की अनुपस्थिति में, बस रिपोर्ट कर सकते हैं कि उन्हें लौटे अनुक्रम के बारे में कुछ भी नहीं पता है, हालांकि यदि IEnumerator या MS-endorsed उत्तराधिकारी (जिसे GetEnumerator कार्यान्वयन द्वारा वापस किया जा सकता है) को इसके अस्तित्व का पता था) अतिरिक्त जानकारी का समर्थन करने के लिए थे, C # को संभवतः set yield optionsइसका समर्थन करने के लिए एक बयान या कुछ समान मिलेगा । अगर ठीक से डिज़ाइन किया गया है, IEnhancedEnumeratorतो बहुत सारे "रक्षात्मक" ToArrayया ToListकॉल को खत्म करके LINQ जैसी चीजों को अधिक उपयोग करने योग्य बना सकता है , विशेष रूप से ...
Supercat

... ऐसे मामलों में जहां Enumerable.Concatबड़े संग्रह को संयोजित करने के लिए चीजों का उपयोग किया जाता है, जो एक छोटे से अपने बारे में बहुत कुछ जानता है जो ऐसा नहीं करता है।
सुपरकैट

10

IEnumerable पुनरावृत्ति के बिना गिनती नहीं कर सकते।

"सामान्य" परिस्थितियों में, IEnumerable या IEnumerable <T> को लागू करने वाली कक्षाओं के लिए संभव होगा, जैसे कि सूची <T>, सूची <T>। संपत्ति वापस करके गणना पद्धति को लागू करने के लिए। हालाँकि, गणना विधि वास्तव में IEnumerable <T> या IEnumerable इंटरफ़ेस पर परिभाषित विधि नहीं है। (केवल वही है, जो वास्तव में, GetEnumerator है।) और इसका मतलब है कि इसके लिए एक वर्ग-विशिष्ट कार्यान्वयन प्रदान नहीं किया जा सकता है।

इसके बजाय, गणना करें कि यह एक विस्तार विधि है, जिसे स्थिर वर्ग पर परिभाषित किया गया है। इसका मतलब यह है कि इसे किसी भी वर्ग के कार्यान्वयन की परवाह किए बिना IEnumerable <T> व्युत्पन्न वर्ग के किसी भी उदाहरण पर बुलाया जा सकता है। लेकिन इसका मतलब यह भी है कि यह एक ही स्थान पर लागू किया जाता है, उन वर्गों में से किसी के लिए बाहरी। निश्चित रूप से इसका मतलब यह है कि इसे इस तरह से लागू किया जाना चाहिए, जो इन वर्ग के इनरल्स से पूरी तरह से स्वतंत्र हो। मतगणना करने का एकमात्र तरीका पुनरावृत्ति है।


जब तक आप पुनरावृति नहीं कर सकते, तब तक गिनने में सक्षम नहीं होने के बारे में यह एक अच्छा बिंदु है। गणना की कार्यक्षमता IEnumerable को लागू करने वाली कक्षाओं से जुड़ी होती है .... इस प्रकार आपको यह जांचना होगा कि IEnumerable किस प्रकार का है (चेक द्वारा कास्टिंग) और फिर आप जानते हैं कि सूची <> और शब्दकोश <> को गिनने और फिर उपयोग करने के कुछ निश्चित तरीके हैं। आप केवल इस प्रकार को जानते हैं। मुझे यह धागा व्यक्तिगत रूप से बहुत उपयोगी लगा, इसलिए आपके उत्तर के साथ-साथ क्रिस के लिए भी धन्यवाद।
पॉजिटिवगूई

1
डैनियल के उत्तर के अनुसार यह उत्तर कड़ाई से सच नहीं है: यदि कोई "गणना" फ़ील्ड है, तो ऑब्जेक्ट "ICollection" को लागू करता है, कार्यान्वयन लागू नहीं होता है। यदि हां, तो यह इसका उपयोग करता है। (क्या यह '08 में वह स्मार्ट था, मुझे नहीं पता।)
टूलमेकरसैट


8

नहीं, सामान्य तौर पर नहीं। गणना करने वालों का उपयोग करने में एक बिंदु यह है कि गणना में वस्तुओं का वास्तविक सेट ज्ञात नहीं है (अग्रिम में, या बिल्कुल भी)।


आपके द्वारा लाया गया महत्वपूर्ण बिंदु यह है कि जब आप उस IEnumerable ऑब्जेक्ट को प्राप्त करते हैं, तब भी आपको यह देखना होगा कि क्या आप यह पता लगा सकते हैं कि यह किस प्रकार का है। यह मेरे कोड में खुद की तरह अधिक IEnumerable का उपयोग करने की कोशिश कर रहे लोगों के लिए एक बहुत ही महत्वपूर्ण बिंदु है।
पॉजिटिव

8

आप System.Linq का उपयोग कर सकते हैं।

using System;
using System.Collections.Generic;
using System.Linq;

public class Test
{
    private IEnumerable<string> Tables
    {
        get {
             yield return "Foo";
             yield return "Bar";
         }
    }

    static void Main()
    {
        var x = new Test();
        Console.WriteLine(x.Tables.Count());
    }
}

आपको परिणाम '2' मिलेगा।


3
यह गैर-जेनेरिक वेरिएंट IEnumerable (बिना टाइप स्पेसियर के) के लिए काम नहीं करता है
Marcel

यदि आप के पास कोई IEnumerable है, तो .Count का कार्यान्वयन सभी आइटमों की गणना कर रहा है। (ICollection के लिए अलग)। ओपी प्रश्न स्पष्ट रूप से "पुनरावृति के बिना" है
जेडीसी

5

अपने तात्कालिक प्रश्न से परे जाकर (जो कि नकारात्मक रूप से पूरी तरह से उत्तर दिया गया है), यदि आप प्रगति की सूचना देते हुए प्रगति की रिपोर्ट करना चाहते हैं, तो आप मेरे ब्लॉग पोस्ट रिपोर्टिंग प्रोग्रेस इन लीनिक क्वेरीज़ के दौरान देखना चाह सकते हैं ।

यह आपको ऐसा करने देता है:

BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += (sender, e) =>
      {
          // pretend we have a collection of 
          // items to process
          var items = 1.To(1000);
          items
              .WithProgressReporting(progress => worker.ReportProgress(progress))
              .ForEach(item => Thread.Sleep(10)); // simulate some real work
      };

4

मैंने IEnumberableसामग्री में उत्तीर्ण की जाँच करने के लिए एक विधि के अंदर इस तरह का उपयोग किया

if( iEnum.Cast<Object>().Count() > 0) 
{

}

इस तरह एक विधि के अंदर:

GetDataTable(IEnumberable iEnum)
{  
    if (iEnum != null && iEnum.Cast<Object>().Count() > 0) //--- proceed further

}

1
ऐसा क्यों करते हैं? "गणना" महंगी हो सकती है, इसलिए एक IEnumerable दिया जाता है, जो भी आउटपुट आपको उपयुक्त चूक के लिए आवश्यक है उसे इनिशियलाइज़ करना सस्ता है, फिर "iEnum" पर पुनरावृत्ति करना शुरू करें। डिफॉल्ट को ऐसे चुनें कि एक खाली "इनेम", जो लूप को कभी निष्पादित नहीं करता है, एक वैध परिणाम के साथ समाप्त होता है। कभी-कभी, इसका मतलब है कि लूप निष्पादित किया गया था या नहीं यह जानने के लिए बूलियन ध्वज को जोड़ना। दी गई है कि अनाड़ी है, लेकिन "गणना" पर भरोसा करना नासमझी है। यदि यह झंडा, जैसे कोड दिखता है की जरूरत है: bool hasContents = false; if (iEnum != null) foreach (object ob in iEnum) { hasContents = true; ... your code per ob ... }
टूलमेकरसैट

... विशेष कोड को जोड़ना भी आसान है जो केवल पहली बार किया जाना चाहिए, या केवल पहली बार के अलावा अन्य पुनरावृत्तियों पर : `... {अगर (है! उत्तर)) {hasContents = true; .. एक समय कोड ..; } और {.. सभी के लिए, लेकिन पहली बार ..} ...} "निस्संदेह, यह आपके सरल दृष्टिकोण की तुलना में अनाड़ी है, जहां एक बार कोड आपके अंदर होगा, लूप से पहले, लेकिन अगर लागत" .Count () "एक चिंता का विषय हो सकता है, तो यह जाने का रास्ता है।
ToolmakerSteve

3

यह .Net के संस्करण पर निर्भर करता है और आपके IEnumerable ऑब्जेक्ट का कार्यान्वयन करता है। Microsoft ने कार्यान्वयन के लिए जाँच करने के लिए IEnumerable.Count विधि निर्धारित की है, और ICollection.Count या ICollection <TSource> का उपयोग करता है। विवरण देखें, यहाँ देखें https://connect.microsoft.com/VisualStudio/feedback/details/454130

और नीचे System.Core के लिए Ildasm से MSIL है, जिसमें System.Linq रहता है।

.method public hidebysig static int32  Count<TSource>(class 

[mscorlib]System.Collections.Generic.IEnumerable`1<!!TSource> source) cil managed
{
  .custom instance void System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       85 (0x55)
  .maxstack  2
  .locals init (class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource> V_0,
           class [mscorlib]System.Collections.ICollection V_1,
           int32 V_2,
           class [mscorlib]System.Collections.Generic.IEnumerator`1<!!TSource> V_3)
  IL_0000:  ldarg.0
  IL_0001:  brtrue.s   IL_000e
  IL_0003:  ldstr      "source"
  IL_0008:  call       class [mscorlib]System.Exception System.Linq.Error::ArgumentNull(string)
  IL_000d:  throw
  IL_000e:  ldarg.0
  IL_000f:  isinst     class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource>
  IL_0014:  stloc.0
  IL_0015:  ldloc.0
  IL_0016:  brfalse.s  IL_001f
  IL_0018:  ldloc.0
  IL_0019:  callvirt   instance int32 class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource>::get_Count()
  IL_001e:  ret
  IL_001f:  ldarg.0
  IL_0020:  isinst     [mscorlib]System.Collections.ICollection
  IL_0025:  stloc.1
  IL_0026:  ldloc.1
  IL_0027:  brfalse.s  IL_0030
  IL_0029:  ldloc.1
  IL_002a:  callvirt   instance int32 [mscorlib]System.Collections.ICollection::get_Count()
  IL_002f:  ret
  IL_0030:  ldc.i4.0
  IL_0031:  stloc.2
  IL_0032:  ldarg.0
  IL_0033:  callvirt   instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<!!TSource>::GetEnumerator()
  IL_0038:  stloc.3
  .try
  {
    IL_0039:  br.s       IL_003f
    IL_003b:  ldloc.2
    IL_003c:  ldc.i4.1
    IL_003d:  add.ovf
    IL_003e:  stloc.2
    IL_003f:  ldloc.3
    IL_0040:  callvirt   instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
    IL_0045:  brtrue.s   IL_003b
    IL_0047:  leave.s    IL_0053
  }  // end .try
  finally
  {
    IL_0049:  ldloc.3
    IL_004a:  brfalse.s  IL_0052
    IL_004c:  ldloc.3
    IL_004d:  callvirt   instance void [mscorlib]System.IDisposable::Dispose()
    IL_0052:  endfinally
  }  // end handler
  IL_0053:  ldloc.2
  IL_0054:  ret
} // end of method Enumerable::Count


2

IEnumerable.Count () फ़ंक्शन का परिणाम गलत हो सकता है। यह परीक्षण करने के लिए एक बहुत ही सरल नमूना है:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;

namespace Test
{
  class Program
  {
    static void Main(string[] args)
    {
      var test = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
      var result = test.Split(7);
      int cnt = 0;

      foreach (IEnumerable<int> chunk in result)
      {
        cnt = chunk.Count();
        Console.WriteLine(cnt);
      }
      cnt = result.Count();
      Console.WriteLine(cnt);
      Console.ReadLine();
    }
  }

  static class LinqExt
  {
    public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int chunkLength)
    {
      if (chunkLength <= 0)
        throw new ArgumentOutOfRangeException("chunkLength", "chunkLength must be greater than 0");

      IEnumerable<T> result = null;
      using (IEnumerator<T> enumerator = source.GetEnumerator())
      {
        while (enumerator.MoveNext())
        {
          result = GetChunk(enumerator, chunkLength);
          yield return result;
        }
      }
    }

    static IEnumerable<T> GetChunk<T>(IEnumerator<T> source, int chunkLength)
    {
      int x = chunkLength;
      do
        yield return source.Current;
      while (--x > 0 && source.MoveNext());
    }
  }
}

परिणाम (7,7,3,3) होना चाहिए, लेकिन वास्तविक परिणाम (7,7,3,17)


1

सबसे अच्छा तरीका मुझे यह एक सूची में परिवर्तित करके गिना जाता है।

IEnumerable<T> enumList = ReturnFromSomeFunction();

int count = new List<T>(enumList).Count;

-1

मैं सुझाव दूंगा कि ToList को बुलाओ। हां, आप एन्यूमरेशन जल्दी कर रहे हैं, लेकिन आपके पास अभी भी आइटम की अपनी सूची है।


-1

यह सबसे अच्छा प्रदर्शन नहीं दे सकता है, लेकिन आप IEQ में एक तत्वों को गिनने के लिए LINQ का उपयोग कर सकते हैं:

public int GetEnumerableCount(IEnumerable Enumerable)
{
    return (from object Item in Enumerable
            select Item).Count();
}

परिणाम "एनुमरेबल.काउंट (?)" करने के बाद बस कैसे अलग होता है?
टूलमेकरसैट

अच्छा सवाल है, या यह वास्तव में इस स्टैकवर्मफ़्लो प्रश्न का उत्तर है।
ह्यूगो


-3

मैं उपयोग IEnum<string>.ToArray<string>().Lengthकरता हूं और यह ठीक काम करता है।


यह ठीक काम करना चाहिए। IEnumerator <Object> .ToArray <Object> .Length
din

1
डैनियल के अति-उत्थित उत्तर में पहले से दिए गए अधिक संक्षिप्त और त्वरित-प्रदर्शन वाले समाधान के बजाय, आप की तुलना में तीन साल पहले लिखे गए "," आप ऐसा क्यों करते हैं IEnum<string>.Count();?
टूलमेकरसेव

तुम सही हो। किसी तरह मैंने डैनियल के जवाब को नजरअंदाज कर दिया, शायद इसलिए कि उन्होंने कार्यान्वयन से उद्धृत किया और मुझे लगा कि उन्होंने एक विस्तार विधि लागू की है और मैं कम कोड के साथ एक समाधान की तलाश कर रहा था।
ओलिवर कोटर

मेरे बुरे उत्तर को संभालने का सबसे स्वीकृत तरीका क्या है? क्या मुझे इसे हटा देना चाहिए?
ओलिवर कोटर

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.