কোনও পুনরাবৃত্তি ছাড়াই একটি আইনেম্যুয়াল <T> থেকে আইটেমগুলি গণনা করুন?


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

ধরা যাক আমি সেগুলিতে পুনরাবৃত্তি করতে চাই এবং # এম এর #n প্রক্রিয়াকরণের মতো কিছু লিখি।

আমার মূল পুনরাবৃত্তির পূর্বে পুনরাবৃত্তি না করে আমি এম এর মান খুঁজে বের করার কোন উপায় আছে কি?

আমি আশা করি আমি নিজেকে পরিষ্কার করে দিয়েছি।

উত্তর:


338

IEnumerableএটি সমর্থন করে না। এটি নকশা দ্বারা। IEnumerableআপনার প্রয়োজনীয় উপাদানগুলির প্রয়োজন হওয়ার আগে আপনার যে উপাদানগুলির জন্য জিজ্ঞাসা করা হয়েছে তা পেতে অলস মূল্যায়ন ব্যবহার করে।

আপনি যদি সেগুলি ব্যবহার করতে পারেন সেগুলির উপরে পুনরাবৃত্তি না করে আইটেমের সংখ্যা জানতে চান ICollection<T>তবে এটির একটি Countসম্পত্তি রয়েছে।


38
যদি আপনার সূচক দ্বারা তালিকাটি অ্যাক্সেস করার প্রয়োজন না হয় তবে আমি আইলিস্টের চেয়ে আইকোলিকেশনটির পক্ষে চাই।
মাইকেল Meadows 21

3
আমি সাধারণত অভ্যাসের বাইরে কেবল তালিকা এবং আইলিস্ট দখল করি। তবে বিশেষত যদি আপনি এগুলি নিজে প্রয়োগ করতে চান তবে আইকোলিকেশনটি আরও সহজ এবং কাউন্টের সম্পত্তিও রয়েছে। ধন্যবাদ!
মেন্ডেল্ট

21
@ শিমি আপনি পুনরাবৃত্তি করুন এবং উপাদানগুলি গণনা করুন। অথবা আপনি লিনক নেমস্পেস থেকে কাউন্ট () কল করুন যা এটি আপনার জন্য করে।
মেন্ডল্ট

1
আইলিস্টের সাথে কেবল আইনিউটারে প্রতিস্থাপন করা কি সাধারণ পরিস্থিতিতে যথেষ্ট?
টেকিন

1
@ হেলগি যেহেতু আইনুনিউরেবলকে অলসভাবে মূল্যায়ন করা হয় আপনি এটি আইলিস্ট ব্যবহার করতে পারবেন না এমন জিনিসগুলির জন্য এটি ব্যবহার করতে পারেন। আপনি এমন একটি ফাংশন তৈরি করতে পারেন যা পাই এর দশমিক দশককে গণনা করে এমন একটি IEnumerable দেয় returns যতক্ষণ আপনি কখনই সম্পূর্ণ ফলাফলটি নিয়ে ভবিষ্যদ্বাণী করার চেষ্টা করবেন না এটি কেবল কাজ করা উচিত। আপনি পাইযুক্ত আইলিস্ট তৈরি করতে পারবেন না। তবে এগুলি সবই একাডেমিক। বেশিরভাগ সাধারণ ব্যবহারের জন্য আমি সম্পূর্ণ সম্মত agree আপনার যদি গণনা প্রয়োজন তবে আপনার আইলিস্ট দরকার need :-)
মেন্ডেল্ট

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
@ অস্কারমিডেরোস পরিগণিতের বেশিরভাগ এক্সটেনশন পদ্ধতির বিভিন্ন ধরণের সিকোয়েন্সগুলির জন্য অনুকূলিতকরণ রয়েছে যেখানে তারা যদি পারে তবে তা সস্তা উপায়ে ব্যবহার করবে।
শিবুমি

1
উল্লিখিত এক্সটেনশনটি। নেট 3.5 থেকে এমএসডিএন-তে নথিভুক্ত রয়েছে ।
খ্রিস্টান

আমার মনে হয় আপনি জেনেরিক টাইপ প্রয়োজন হবে না 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();
ড্যানিয়েল আরউইকার er

87

কেবল অতিরিক্ত কিছু তথ্য যুক্ত করা হচ্ছে:

Count()এক্সটেনশন সবসময় পুনরুক্তি না। লিনকে টু এসকিএল বিবেচনা করুন, যেখানে গণনাটি ডাটাবেসে যায় তবে সমস্ত সারি ফিরিয়ে আনার পরিবর্তে এটি এসকিএল জারি করেCount() কমান্ড এবং পরিবর্তে ফলাফলটি প্রদান করে।

অতিরিক্তভাবে, সংকলকটি (বা রানটাইম) যথেষ্ট স্মার্ট যে এটি যদি অবজেক্ট Count()পদ্ধতিতে থাকে তবে তা এটি কল করবে । সুতরাং এটি না হিসাবে অন্যান্য প্রতিক্রিয়াকারীকে সম্পূর্ণরূপে অজ্ঞ হচ্ছে এবং সবসময় অর্ডার উপাদান গণনা করার জন্য iterating বলে।

অনেক ক্ষেত্রে যেখানে প্রোগ্রামার কেবল এক্সটেনশন পদ্ধতিটি if( enumerable.Count != 0 )ব্যবহার করে পরীক্ষা করছে Any(), যেমন if( enumerable.Any() ) লিনকের অলস মূল্যায়নের সাথে আরও দক্ষ কারণ এটি কোনও উপাদান রয়েছে কিনা তা নির্ধারণ করতে পারলে এটি শর্ট সার্কিট করতে পারে। এটি আরও পাঠযোগ্য


2
সংগ্রহ এবং অ্যারে সম্পর্কিত। যদি আপনি কোনও সংগ্রহ ব্যবহার করে থাকেন তবে .Countসম্পত্তিটি ব্যবহার করুন কারণ এটি সর্বদা এটির আকার জানেন knows অনুসন্ধান করার collection.Countসময় কোনও অতিরিক্ত গণনা নেই, এটি কেবল ইতিমধ্যে জানা গণনাটি প্রদান করে returns জন্য একই Array.lengthহিসাবে যতদূর আমি জানি। যাইহোক, .Any()উত্সটির ব্যবহারকারীর তালিকা ব্যবহার করে using (IEnumerator<TSource> enumerator = source.GetEnumerator())এবং এটি করতে পারলে সত্য ফেরত দেয় enumerator.MoveNext()। সংগ্রহের জন্য :, if(collection.Count > 0)অ্যারে: if(array.length > 0)এবং অগণিতগুলি করেন if(collection.Any())
নো

1
প্রথম বিন্দু কঠোরভাবে সত্য নয় ... এসকিউএল LINQ ব্যবহার এই এক্সটেনশনটি পদ্ধতি যা হিসাবে একই নয় এই এক । আপনি যদি দ্বিতীয়টি ব্যবহার করেন, গণনাটি মেমোরিতে সঞ্চালিত হয়, এসকিউএল ফাংশন হিসাবে নয়
আলেক্সফক্সগিল

1
@ অ্যালেক্সফক্সগিল সঠিক। আপনি যদি সুস্পষ্টরূপে আপনার কাস্ট IQueryably<T>একটি থেকে IEnumerable<T>এটি একটি SQL গণনা ইস্যু করা হবে না। আমি যখন এটি লিখেছিলাম, লিনক থেকে এসকিএল নতুন ছিল; আমি মনে করি যে আমি কেবল ব্যবহারের দিকে চাপ Any()দিচ্ছিলাম কারণ গণনা, সংগ্রহ এবং স্কয়ারের জন্য এটি অনেক বেশি দক্ষ এবং পাঠযোগ্য (সাধারণভাবে) ছিল। উত্তর উন্নতির জন্য ধন্যবাদ।
রবার্ট পলসন 4

12

আমার এক বন্ধুর ব্লগ পোস্টগুলির একটি সিরিজ রয়েছে যা আপনি কেন এটি করতে পারবেন না তার একটি চিত্র সরবরাহ করে। তিনি এমন একটি ফাংশন তৈরি করেন যা একটি আইনুনামেবল ফিরিয়ে দেয় যেখানে প্রতিটি পুনরাবৃত্তি পরবর্তী সমস্ত মৌলিক সংখ্যা, সমস্ত পথে ফেরত দেয়ulong.MaxValue এবং আপনি যতক্ষণ না জিজ্ঞাসা না করেন পরবর্তী আইটেমটি গণনা করা হয় না। দ্রুত, পপ প্রশ্ন: কতটি আইটেম ফিরে আসে?

পোস্টগুলি এখানে, তবে সেগুলি দীর্ঘ ধরনের:

  1. লুপগুলি ছাড়িয়ে (অন্যান্য পোস্টগুলিতে ব্যবহৃত একটি প্রাথমিক গণ্যযোগ্যতা শ্রেণি সরবরাহ করে)
  2. Iterate এর প্রয়োগ (প্রাথমিক প্রয়োগ)
  3. ক্রেজি এক্সটেনশন পদ্ধতি: ToLazyList (পারফরম্যান্স অপ্টিমাইজেশন)

2
আমার সত্যিকার অর্থেই এমএস এমনিশিয়ালগণকে নিজের সম্পর্কে কী বলতে পারে ("কোনও কিছু জানে না" বৈধ উত্তর হওয়ার সাথে সাথে) বর্ণনা করার জন্য একটি উপায় নির্ধারণ করে দিয়েছিলেন। "আপনি কি নিজেকে সসীম হতে জানেন", "আপনি কি নিজেকে এন এর উপাদানগুলির চেয়ে কম সীমাবদ্ধ হতে", এবং "আপনি কি নিজেকে অসীম হতে জানেন" এই জাতীয় প্রশ্নের উত্তর দিতে কোনও অসুবিধা হওয়ার দরকার নেই, কারণ যে কোনও গণনাযোগ্য বৈধভাবে হতে পারে (যদি সহায়তা না করে) তাদের সকলকে "না" উত্তর দিন। যদি এই জাতীয় প্রশ্ন জিজ্ঞাসার জন্য কোনও স্ট্যান্ডার্ড উপায় থাকে, তবে
গণকের

1
... (যেহেতু তারা বলতে পারত যে তারা এটি করেছে), এবং কোডটি ধরে নেওয়ার জন্য যে অন্তর্ভুক্তকারীরা অন্তহীন ক্রমগুলি ফিরিয়ে নেওয়ার দাবি করেন না তাদের সীমাবদ্ধ হতে পারে। নোট করুন যে এই জাতীয় প্রশ্ন জিজ্ঞাসা করার উপায় সহ (বয়লারপ্লেট হ্রাস করতে, সম্ভবত কোনও সম্পত্তি কোনও EnumerableFeaturesজিনিস ফেরত দিতে পারে) এর জন্য গণ্যকারীদের কোনও অসুবিধা করার দরকার পড়বে না, তবে এই জাতীয় প্রশ্ন জিজ্ঞাসা করতে সক্ষম হবেন (পাশাপাশি কিছু "আপনি কি প্রতিশ্রুতি দিতে পারেন?" সর্বদা আইটেমগুলির একই ক্রম ফিরিয়ে দিন "," আপনি কী এমন কোডের সাথে নিরাপদে প্রকাশ করতে পারেন যা আপনার অন্তর্নিহিত সংগ্রহকে পরিবর্তন না করে "ইত্যাদি) খুব কার্যকর হবে।
সুপারক্যাট

এটি বেশ দুর্দান্ত হবে তবে আমি এখন নিশ্চিত যে এটির পুনরায় ব্লকগুলির সাথে কত ভাল জাল হবে sh আপনার কিছু বিশেষ "ফলন বিকল্প" বা কিছু দরকার need অথবা পুনরুক্তি পদ্ধতিটি সাজানোর জন্য বৈশিষ্ট্যগুলি ব্যবহার করুন।
জোয়েল কোহোর্ন

1
আইটেমেটর ব্লকগুলি, অন্য কোনও বিশেষ ঘোষণার অনুপস্থিতিতে কেবল রিপোর্ট করতে পারে যে তারা প্রত্যাবর্তিত ক্রম সম্পর্কে কিছুই জানে না, যদিও আইইনমিটার বা কোনও এমএস-অনুমোদিত অনুমোদিত উত্তরসূরি (যা তার অস্তিত্ব সম্পর্কে জানত গেটইনুমেরেটর বাস্তবায়ন দ্বারা ফিরিয়ে দেওয়া যেতে পারে) অতিরিক্ত তথ্য সমর্থন করা ছিল, সি # সম্ভবত একটি set yield optionsবিবৃতি বা এটি সমর্থন অনুরূপ কিছু পেতে পারে। যদি সঠিকভাবে ডিজাইন করা IEnhancedEnumeratorহয় তবে একটি অনেকগুলি "প্রতিরক্ষামূলক" ToArrayবা ToListকলগুলি মুছে ফেলে লিনকির মতো জিনিসগুলিকে আরও ব্যবহারযোগ্য করে তুলতে পারে , বিশেষত ...
সুপারক্যাট

... এমন ক্ষেত্রে যখন Enumerable.Concatবড় সংগ্রহগুলি একত্রিত করতে পছন্দসই জিনিস ব্যবহার করা হয় যা একটি ছোট সংগ্রহের সাথে নিজের সম্পর্কে অনেক কিছু জানে that
সুপারক্যাট

10

সংখ্যাগুণ পুনরাবৃত্তি না করে গণনা করতে পারে না।

"সাধারণ" পরিস্থিতিতে, তালিকা <T> হিসাবে তালিকার <T> হিসাবে গণনা পদ্ধতি বাস্তবায়নের জন্য IEnumerable বা IEnumerable <T> প্রয়োগকারী শ্রেণীর পক্ষে গণনা পদ্ধতি কার্যকর করা সম্ভব হবে C অ্যাকাউন্টের সম্পত্তি। যাইহোক, গণনা পদ্ধতিটি আসলে IEnumerable <T> বা IEnumerable ইন্টারফেসে সংজ্ঞায়িত কোনও পদ্ধতি নয়। (প্রকৃতপক্ষে একমাত্র হ'ল getEnumerator।) এবং এর অর্থ এটি একটি শ্রেণি-নির্দিষ্ট বাস্তবায়ন সরবরাহ করা যায় না।

বরং গণনা করুন এটি একটি এক্সটেনশন পদ্ধতি, স্ট্যাটিক শ্রেণিতে পরিগণিত হিসাবে সংজ্ঞায়িত। এর অর্থ এই যে কোনও শ্রেণীর প্রয়োগ নির্বিশেষে কোনও আইনিম্যুয়াল <T> উত্পন্ন শ্রেণীর যে কোনও উদাহরণে এটি কল করা যেতে পারে। তবে এর অর্থ এটিও একক স্থানে প্রয়োগ করা হয়, যে কোনও শ্রেণীর বাইরে। অবশ্যই কোনটির অর্থ হল যে এটি অবশ্যই এমনভাবে প্রয়োগ করা উচিত যা এই শ্রেণীর অভ্যন্তরগুলি থেকে সম্পূর্ণ স্বতন্ত্র। গণনা করার একমাত্র উপায় হ'ল পুনরাবৃত্তি।


আপনি পুনরাবৃত্তি না করে এটি গণনা করতে সক্ষম না হওয়া সম্পর্কে এটি একটি উত্তম বিষয়। গণনা কার্যকারিতা IEnumerable বাস্তবায়নকারী ক্লাসগুলির সাথে আবদ্ধ .... সুতরাং আপনাকে কী ধরণের IEnumerable আগমন করা হবে তা পরীক্ষা করতে হবে (কাস্টিং দ্বারা চেক করুন) এবং তারপরে আপনি জানেন যে তালিকা <> এবং অভিধান <> গণনা করার নির্দিষ্ট উপায় রয়েছে এবং তারপরে ব্যবহার করুন এগুলি কেবল আপনার টাইপটি জানার পরে। আমি এই থ্রেডটি ব্যক্তিগতভাবে খুব দরকারী বলে খুঁজে পেয়েছি তাই ক্রিসকেও উত্তর দেওয়ার জন্য ধন্যবাদ
PositiveGuy

1
ড্যানিয়েলের উত্তর অনুসারে এই উত্তরটি কঠোরভাবে সত্য নয়: বাস্তবায়ন পরীক্ষা করে দেখায় যে বস্তুটি "আইকোলিকেশন" প্রয়োগ করে, যার একটি "গণনা" ক্ষেত্র রয়েছে। যদি তাই হয় তবে এটি ব্যবহার করে। (এটি '08-তে স্মার্ট ছিল কিনা তা আমি জানি না))
টুলমেকারস্টেভ


8

না, সাধারণভাবে নয়। গণনাকারী ব্যবহারের একটি বিষয় হ'ল যে গণনাতে বস্তুর প্রকৃত সেটটি জানা নেই (আগাম বা এমনকি কিছুতেই)।


আপনি যে গুরুত্বপূর্ণ পয়েন্টটি উত্থাপন করেছেন তা হ'ল আপনি যখন সেই আইনিম্যারেবল অবজেক্টটি পেয়েছেন তখন আপনাকে দেখতে হবে এটি কী ধরণের তা নির্ধারণের জন্য আপনি এটি ফেলে দিতে পারেন কিনা। এটি আমার কোডে নিজের মতো আরও আইনিউনামেবল ব্যবহার করার চেষ্টা করছে তাদের কাছে এটি একটি অত্যন্ত গুরুত্বপূর্ণ বিষয়।
PositiveGuy

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 (টাইপ নির্দিষ্টকরণ ছাড়াই)
মার্সেল

.আরউসেন্টের প্রয়োগটি যদি আপনার একটি অনুমিত হয় তবে সমস্ত আইটেমকে গণনা করা হবে। (আইকোলিকেশন জন্য পৃথক)। ওপি প্রশ্নটি পরিষ্কারভাবে "পুনরাবৃত্তি না করে"
জেডিসি

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
কেন যে? "গণনা" ব্যয়বহুল হতে পারে, সুতরাং একটি আইনামিউরেবল দেওয়া হলে, আপনার যথাযথ ডিফল্টগুলির জন্য যা প্রয়োজন ফলাফলগুলি শুরু করা সস্তা then ডিফল্টগুলি বেছে নিন যেমন একটি খালি "আইএনমন", যা কখনই লুপটি কার্যকর করে না, একটি বৈধ ফলাফল দিয়ে শেষ হয়। কখনও কখনও, এর অর্থ লুপটি কার্যকর হয়েছিল কিনা তা জানার জন্য বুলিয়ান পতাকা যুক্ত করা। অনুমোদিত যে আনাড়ি, কিন্তু "গণনা" উপর নির্ভর করা বোকামি বলে মনে হচ্ছে। যদি এটি পতাকা, মত কোড সৌন্দর্য প্রয়োজন: bool hasContents = false; if (iEnum != null) foreach (object ob in iEnum) { hasContents = true; ... your code per ob ... }
স্টেভ

... বিশেষ কোড যুক্ত করাও সহজ যা কেবল প্রথমবারেই করা উচিত, বা কেবল প্রথমবারের চেয়ে অন্য পুনরাবৃত্তিতে : `... {if (! hasContents) {hasContents = true; ..একটা সময় কোড ..; } অন্যথায় {.. প্রথমবারের জন্য কোড কিন্তু প্রথমবারের জন্য ..} ...} "স্বীকার করুন, এটি আপনার সাধারণ পদ্ধতির চেয়ে ক্ল্যামিয়র, যেখানে লুপের আগে ওয়ান-টাইম কোড আপনার অভ্যন্তরে থাকবে তবে যদি" .Count () "একটি উদ্বেগের বিষয় হতে পারে, তাহলে এই যেতে উপায়।
ToolmakerSteve

3

এটি নেট ও সংস্করণ আপনার আইইনিউরেবল অবজেক্টের প্রয়োগের উপর নির্ভর করে। মাইক্রোসফট, বাস্তবায়ন জন্য চেক করতে IEnumerable.Count পদ্ধতি নির্ধারণ করেছে, এবং ICollection.Count বা ICollection <TSource> .Count ব্যবহার এখানে বিস্তারিত দেখুন https://connect.microsoft.com/VisualStudio/feedback/details/454130

এবং নীচে System.Core এর জন্য Ildasm থেকে এমএসআইএল রয়েছে, যেখানে সিস্টেম.লিংক থাকে।

.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

আইইনুমারেবল.একউন্ট () ফাংশনের ফলাফল ভুল হতে পারে। এটি পরীক্ষা করার জন্য একটি খুব সাধারণ নমুনা:

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

আমি টোলিস্ট কল করার পরামর্শ দেব। হ্যাঁ আপনি প্রথম দিকে গণনাটি করছেন তবে আপনার আইটেমের তালিকায় এখনও অ্যাক্সেস রয়েছে।


-1

এটি সর্বোত্তম পারফরম্যান্স নাও পেতে পারে, তবে আপনি একটি অনুমিত পরিমাণে উপাদানগুলি গণনা করতে লিনকিউ ব্যবহার করতে পারেন:

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

কীভাবে ফলাফলটি কেবল "` রিটার্ন এনিউমারেবল.কউন্ট (); "করা থেকে আলাদা?
নির্মাতা স্টিভ

ভাল প্রশ্ন, বা এটি আসলে এই স্ট্যাকওভারফ্লো প্রশ্নের একটি উত্তর।
হুগো

-1

আমি মনে করি এটি করার সবচেয়ে সহজ উপায়

Enumerable.Count<TSource>(IEnumerable<TSource> source)

তথ্যসূত্র: system.linq.enumerable


প্রশ্নটি হল "পুনরাবৃত্তি না করে একটি আইনিম্যুয়াল <T> থেকে আইটেমগুলি গণনা করুন?" কিভাবে এই উত্তর দেয়?
বুদ্ধিমানতা

-3

আমি ব্যবহার করি IEnum<string>.ToArray<string>().Lengthএবং এটি ভাল কাজ করে।


এটি ভাল কাজ করা উচিত। আইনিউমরেটর <অবজেক্ট>। টুআরে << বিষয়>। দৈর্ঘ্য
দিন

1
আপনার চেয়ে তিন বছর আগে লেখা ড্যানিয়েলের উচ্চ-উত্তরের উত্তরে ইতিমধ্যে দেওয়া আরও সংক্ষিপ্ত এবং দ্রুত-সম্পাদনযোগ্য সমাধানের চেয়ে আপনি কেন এটি করেন IEnum<string>.Count();? " "?
নির্মাতা স্টিভ

তুমি ঠিক. কোনওভাবেই আমি ড্যানিয়েলের উত্তরটিকে উপেক্ষা করেছি, কারণ তিনি বাস্তবায়নটি উদ্ধৃত করেছেন এবং আমি ভেবেছিলাম যে সে একটি এক্সটেনশন পদ্ধতি কার্যকর করেছে এবং আমি কম কোড সহ একটি সমাধান খুঁজছি।
অলিভার ক্যাটর

আমার খারাপ উত্তর পরিচালনা করার সবচেয়ে গ্রহণযোগ্য উপায় কী? আমি এটি মুছে ফেলা উচিত?
অলিভার ক্যাটর

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.