কেউ আমাকে আইনিউবারেবল এবং আইনিউমরেটর ব্যাখ্যা করতে পারেন? [বন্ধ]


272

কেউ আমাকে আইনিউবারেবল এবং আইনিউমরেটর ব্যাখ্যা করতে পারেন?

উদাহরণস্বরূপ, ফোরচের ওপরে কখন এটি ব্যবহার করবেন? আইইনুমারেবল এবং আইনিমরেটর এর মধ্যে পার্থক্য কী? আমাদের এটি কেন ব্যবহার করা দরকার?


54
এটি জাভা এবং জাভাস্ক্রিপ্টের পরে সবচেয়ে খারাপ নামকরণের মিশ্রণ
মথি

@ ম্যাথলক আপনি কী বলতে চাইছেন তা ব্যাখ্যা করতে পারবেন?
ডেভিড ক্ল্যাম্পফনার

উত্তর:


274

উদাহরণস্বরূপ, ফোরচের ওপরে কখন এটি ব্যবহার করবেন?

আপনি IEnumerable"ওভার" ব্যবহার করবেন না foreach। বাস্তবায়ন সম্ভবIEnumerable ব্যবহার করে তোলে ।foreach

আপনি যখন কোডটি লিখবেন:

foreach (Foo bar in baz)
{
   ...
}

এটি কার্যত লেখার সমতুল্য:

IEnumerator bat = baz.GetEnumerator();
while (bat.MoveNext())
{
   bar = (Foo)bat.Current
   ...
}

"কার্যকরী সমতুল্য" দ্বারা, এর অর্থ হ'ল সংকলক কোডটিকে রূপান্তরিত করে। আপনি ব্যবহার করতে পারবেন না foreachউপর bazএই উদাহরণে যদি না baz কার্যকরী IEnumerable

IEnumerableএর অর্থ হল যে bazপদ্ধতিটি কার্যকর করে

IEnumerator GetEnumerator()

IEnumeratorবস্তু এই পদ্ধতি আয় পদ্ধতি বাস্তবায়ন করতে হবে

bool MoveNext()

এবং

Object Current()

প্রথম পদ্ধতিটি পরবর্তী বস্তুটিতে অগ্রসর হয় যা IEnumerableগণক তৈরি করেছিল, falseএটি সম্পন্ন হলে ফিরে আসে এবং দ্বিতীয়টি বর্তমান অবজেক্টটি প্রদান করে।

.NET এর মধ্যে যে কোনও কিছুই আপনি প্রয়োগগুলির মাধ্যমে পুনরাবৃত্তি করতে পারেন IEnumerable। যদি আপনি নিজের শ্রেণি তৈরি করে থাকেন এবং এটি ইতিমধ্যে প্রয়োগকারী কোনও শ্রেণীর উত্তরাধিকার সূত্রে না পেয়ে থাকে তবে IEnumerableআপনি প্রয়োগের মাধ্যমে foreachবিবৃতিতে আপনার শ্রেণিকে ব্যবহারযোগ্য করে তুলতে পারেন IEnumerable(এবং একটি নতুন শ্রেণি তৈরি করে যা এর নতুন GetEnumeratorপদ্ধতিটি ফিরে আসবে)।


15
আমি মনে করি যখন মূল পোস্টারটি "ওভার ফরচ" বলেছিল, তখন তার অর্থ ছিল "যখন আমি ফোরচ লুপ ব্যবহার না করে স্পষ্টভাবে গেটইনিউমরেটর () / মুভনেক্সট () কল করব"। এর মূল্য কী।
এমকিপিপি

6
আহ, আমি ঠিক বলেছি ঠিক আছে, উত্তরটি আমার পোস্টে অন্তর্ভুক্ত রয়েছে: এটি কোনও ব্যাপার নয়, যেহেতু সংকলক যাই হোক না কেন তা করে। তাই সবচেয়ে সহজ, অর্থাত্ ব্যবহার করুন ach
রবার্ট রসনি 19

12
এই উত্তরটি পুরো গল্পটি বলে না। গণনামূলক অবজেক্টগুলির আইনিউমেন্টেবল প্রয়োগ করতে হবে না; তাদের কেবলমাত্র একটি getEnumerator পদ্ধতি থাকা দরকার যা কোনও ধরণের উদাহরণ দেয় যা ঘুরে ফিরে কোনও bool MoveNext()পদ্ধতি এবং Currentকোনও প্রকারের সম্পত্তি থাকে। এই "হাঁসের টাইপিং" পদ্ধতির মূল্য # ধরণের সংগ্রহগুলি গণনার সময় বক্সিং এড়ানোর উপায় হিসাবে সি # 1.0 তে প্রয়োগ করা হয়েছিল।
ফুগ

3
উপরে থেকে ব্যাখ্যা এবং ওয়ার্থথ্রু মাধ্যমে কাজ করে : আপনার গ্রেট উত্স আছে (টি) এর IEnumerable বাস্তবায়ন
ruedi

4
এই ধরণের কি সি ++ এর মতো iterator?
ম্যাট জি

161

আইনিউমারেবল এবং আইনিউমারেটর ইন্টারফেস

বিদ্যমান .NET ইন্টারফেস বাস্তবায়নের প্রক্রিয়াটি পরীক্ষা করার জন্য, প্রথমে IEnumerable এবং IEnumerator এর ভূমিকাটি দেখি। মনে রাখবেন যে সি # পূর্বাঞ্চ নামের একটি কীওয়ার্ড সমর্থন করে যা আপনাকে কোনও অ্যারের প্রকারের সামগ্রীতে পুনরাবৃত্তি করতে দেয়:

// Iterate over an array of items.
int[] myArrayOfInts = {10, 20, 30, 40};
foreach(int i in myArrayOfInts)
{
   Console.WriteLine(i);
}

যদিও মনে হতে পারে যে কেবল অ্যারে টাইপগুলিই এই নির্মাণটি ব্যবহার করতে পারে, তবে এই বিষয়টির সত্যতা হ'ল getEnumerator () নামের একটি পদ্ধতি সমর্থনকারী কোনও প্রকার পূর্বাপর নির্মাণটি দ্বারা মূল্যায়ন করা যায় can উদাহরণস্বরূপ, আমাকে অনুসরণ করুন!

মনে করুন আমাদের একটি গ্যারেজ ক্লাস রয়েছে:

// Garage contains a set of Car objects.
public class Garage
{
   private Car[] carArray = new Car[4];
   // Fill with some Car objects upon startup.
   public Garage()
   {
      carArray[0] = new Car("Rusty", 30);
      carArray[1] = new Car("Clunker", 55);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
}

আদর্শভাবে, ডেটা মানগুলির একটি অ্যারের মতো, পূর্ববর্তী নির্মাণগুলি ব্যবহার করে গ্যারেজ অবজেক্টের সাবাইটামগুলি দিয়ে পুনরাবৃত্তি করা সুবিধাজনক হবে:

// This seems reasonable ...
public class Program
{
   static void Main(string[] args)
   {
      Console.WriteLine("***** Fun with IEnumerable / IEnumerator *****\n");
      Garage carLot = new Garage();
      // Hand over each car in the collection?
      foreach (Car c in carLot)
      {
         Console.WriteLine("{0} is going {1} MPH",
         c.PetName, c.CurrentSpeed);
      }
      Console.ReadLine();
   }
}

দুঃখের বিষয়, সংকলক আপনাকে অবহিত করে যে গ্যারেজ শ্রেণিটি getEnumerator () নামে একটি পদ্ধতি প্রয়োগ করে না। এই পদ্ধতিটি আইমুনিউরেবল ইন্টারফেস দ্বারা আনুষ্ঠানিকভাবে প্রবর্তিত, যা সিস্টেমের মধ্যে লুকানো পাওয়া যায় Col সংগ্রহের নেমস্পেসে। এই আচরণকে সমর্থন করে এমন শ্রেণি বা কাঠামো বিজ্ঞাপন দেয় যে তারা কলারের কাছে থাকা সাবাইটাইটগুলি প্রকাশ করতে সক্ষম হয় (উদাহরণস্বরূপ, আগাম কীওয়ার্ডটি নিজেই)। এখানে এই মান। নেট ইন্টারফেসের সংজ্ঞা দেওয়া হল:

// This interface informs the caller
// that the object's subitems can be enumerated.
public interface IEnumerable
{
   IEnumerator GetEnumerator();
}

আপনি দেখতে পাচ্ছেন, গেটইনিউমরেটর () পদ্ধতিটি সিস্টেম.কলেকশনস.আইনামেটর নামে আরও একটি ইন্টারফেসের রেফারেন্স দেয়। এই ইন্টারফেসটি কলকারকে আইইনিউরেবল-সামঞ্জস্যপূর্ণ ধারক দ্বারা অন্তর্ভুক্ত অভ্যন্তরীণ বস্তুগুলি অতিক্রম করার অনুমতি দেওয়ার জন্য অবকাঠামো সরবরাহ করে:

// This interface allows the caller to
// obtain a container's subitems.
public interface IEnumerator
{
   bool MoveNext (); // Advance the internal position of the cursor.
   object Current { get;} // Get the current item (read-only property).
   void Reset (); // Reset the cursor before the first member.
}

আপনি যদি এই ইন্টারফেসগুলিকে সমর্থন করতে গ্যারেজ প্রকারটি আপডেট করতে চান তবে আপনি দীর্ঘ রাস্তাটি নিতে পারেন এবং প্রতিটি পদ্ধতি নিজেই প্রয়োগ করতে পারেন। আপনি অবশ্যই getEnumerator (), মুভনেক্সট (), বর্তমান এবং রিসেট () এর স্বনির্ধারিত সংস্করণগুলি সরবরাহ করতে নিখরচায় একটি সহজ উপায় আছে। যেমন সিস্টেম.আরয়ের ধরণ (সেই সাথে আরও অনেকগুলি সংগ্রহের ক্লাস) ইতিমধ্যে আইইনিউমারেবল এবং আইনিউমরেটর প্রয়োগ করে, আপনি কেবল অনুরোধটি সিস্টেমের কাছে অর্পণ করতে পারেন r অ্যারে নিম্নরূপ:

using System.Collections;
...
public class Garage : IEnumerable
{
   // System.Array already implements IEnumerator!
   private Car[] carArray = new Car[4];
   public Garage()
   {
      carArray[0] = new Car("FeeFee", 200);
      carArray[1] = new Car("Clunker", 90);
      carArray[2] = new Car("Zippy", 30);
      carArray[3] = new Car("Fred", 30);
   }
   public IEnumerator GetEnumerator()
   {
      // Return the array object's IEnumerator.
      return carArray.GetEnumerator();
   }
}

আপনি আপনার গ্যারেজ প্রকারটি আপডেট করার পরে, আপনি নিরাপদে সি # ফরচ নির্মাণের মধ্যে টাইপটি নিরাপদে ব্যবহার করতে পারেন। তদ্ব্যতীত, GetEnumerator () পদ্ধতিটি সর্বজনীনভাবে সংজ্ঞায়িত করা হয়েছে, অবজেক্ট ব্যবহারকারী আইইনুমেটর টাইপের সাথেও ইন্টারেক্ট করতে পারে:

// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);

তবে আপনি যদি অবজেক্ট স্তর থেকে আইনিউনামেবলের কার্যকারিতা আড়াল করতে পছন্দ করেন তবে কেবল স্পষ্টভাবে ইন্টারফেস প্রয়োগের ব্যবহার করুন:

IEnumerator IEnumerable.GetEnumerator()
{
  // Return the array object's IEnumerator.
  return carArray.GetEnumerator();
}

এটি করার মাধ্যমে, নৈমিত্তিক অবজেক্ট ব্যবহারকারী গ্যারেজের গেটইমুনিটার () পদ্ধতিটি খুঁজে পাবেন না, যখন ফোরচ কন্সট্রাক্ট প্রয়োজনীয়তার পরে ব্যাকগ্রাউন্ডে ইন্টারফেসটি পাবেন।

থেকে অভিযোজিত প্রো সি # 5.0 এবং .NET 4.5 ফ্রেমওয়ার্ক


1
চমত্কার উত্তর, আপনাকে ধন্যবাদ! যদিও আমি একটি প্রশ্ন আছে। প্রথম উদাহরণে আপনি ফোরচ ব্যবহার করে অ্যারেটি লুপ করেন তবে তারপরে আপনি দ্বিতীয় উদাহরণে এটি করতে পারবেন না। এটি কি কারণ অ্যারেটি একটি শ্রেণিতে আছে বা কারণ এতে অবজেক্ট রয়েছে?
কালেব পামকুইস্ট 23'17

দুর্দান্ত ব্যাখ্যার জন্য আপনাকে ধন্যবাদ। আমার শুধু প্রশ্ন কেন শুধু একটি পদ্ধতি আছে নয় Garageযে পায় carArray? ইতিমধ্যে এটি করে GetEnumeratorচলেছে তাই আপনাকে নিজের প্রয়োগ করতে হবে না Array। উদাহরণস্বরূপforeach(Car c in carLot.getCars()) { ... }
নিক রোল্যান্ডো

62

আইনিউমারেবল কার্যকর করার অর্থ আপনার শ্রেণি একটি আইনিমেটর অবজেক্টকে ফেরত দেয়:

public class People : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        // return a PeopleEnumerator
    }
}

আইনিমরেটর কার্যকর করার অর্থ আপনার শ্রেণি পুনরাবৃত্তির জন্য পদ্ধতি এবং বৈশিষ্ট্যগুলি প্রদান করে:

public class PeopleEnumerator : IEnumerator
{
    public void Reset()...

    public bool MoveNext()...

    public object Current...
}

তবুও পার্থক্য


1
সুন্দর, এটি ব্যাখ্যা করে (অন্যান্য পোস্টগুলির সাথে একসাথে) কীভাবে আপনার ক্লাসটিকে এমন এক রূপান্তর করতে পারে যা আপনি "ফোরচ" ব্যবহার করতে পারেন তার সামগ্রীতে পুনরাবৃত্তি করতে।
কনটাঙ্গো

54

অ্যানালগি + কোড ওয়াকথ্রু মাধ্যমে ব্যাখ্যা

কোড ছাড়াই প্রথমে একটি ব্যাখ্যা, তারপরে আমি এটি পরে যুক্ত করব।

ধরা যাক আপনি একটি বিমান সংস্থা পরিচালনা করছেন running এবং প্রতিটি বিমানে আপনি বিমানটিতে উড়ন্ত যাত্রীদের সম্পর্কে তথ্য জানতে চান। মূলত আপনি প্লেনটিকে "ট্র্যাভার্স" করতে সক্ষম হতে চান। অন্য কথায়, আপনি সামনের সিটে শুরু করতে সক্ষম হতে চান, এবং তারপরে বিমানের পিছনের দিকে যাত্রা করার জন্য যাত্রীদের কিছু তথ্য জিজ্ঞাসা করুন: তারা কে, তারা কোথা থেকে এসেছে ইত্যাদি ইত্যাদি একটি বিমান কেবল এটি করতে পারে , যদি এটি হয়:

  1. গণনাযোগ্য, এবং
  2. যদি এটির একটি পাল্টা থাকে।

কেন এই প্রয়োজনীয়তা? কারণ এটাই ইন্টারফেসের প্রয়োজন।

যদি এটি তথ্য ওভারলোড হয় তবে আপনার যা যা জানা দরকার তা হ'ল আপনি প্রথম থেকে শুরু করে শেষের দিকে যাত্রা করে বিমানের প্রতিটি যাত্রীকে কিছু প্রশ্ন জিজ্ঞাসা করতে সক্ষম হতে চান।

গণনা মানে কি?

যদি কোনও এয়ারলাইন "গণনাযোগ্য" হয় তবে এর অর্থ হ'ল বিমানটিতে বিমানের একজন পরিচারক উপস্থিত থাকতে হবে, যার একমাত্র কাজ গণনা করা - এবং এই ফ্লাইট অ্যাটেন্ডেন্টকে খুব নির্দিষ্ট পদ্ধতিতে গণনা করতে হবে:

  1. কাউন্টার / ফ্লাইট অ্যাটেন্ড্যান্ট প্রথম যাত্রীর আগে অবশ্যই শুরু করা উচিত (সবার সামনে যেখানে তারা সুরক্ষা ডেমো করেন, লাইফ জ্যাকেট কীভাবে লাগাতে পারেন)।
  2. তিনি / তিনি (অর্থাত্ ফ্লাইট অ্যাটেন্ডেন্ট) প্রথম আসনে আইলটি উপরে "এগিয়ে যেতে" হবে।
  3. তারপরে সে রেকর্ড করতে হবে: (i) ব্যক্তি আসনে কে এবং (ii) আইলটিতে তাদের বর্তমান অবস্থান।

পদ্ধতি গণনা

এয়ারলাইন্সের ক্যাপ্টেন প্রতিটি যাত্রীর মতো এবং যখন তাদের তদন্ত বা গণনা করা হয় সে সম্পর্কে একটি প্রতিবেদন চান। সুতরাং প্রথম আসনে ওই ব্যক্তির সাথে কথা বলার পরে, ফ্লাইট-অ্যাটেন্ডেন্ট / কাউন্টার তারপরে ক্যাপ্টেনকে রিপোর্ট করে এবং যখন প্রতিবেদনটি দেওয়া হয়, তখন কাউন্টারটি আইলটিতে তার / তার সঠিক অবস্থানটি মনে রাখে এবং সে যেখানে চলে গেছে তার ডানদিকে গণনা অবিরত রাখে বন্ধ।

এই পদ্ধতিতে অধিনায়ক সর্বদা বর্তমান ব্যক্তির তদন্তকৃত তথ্য সম্পর্কিত তথ্য রাখতে সক্ষম হন। এইভাবে, যদি তিনি জানতে পারেন যে এই ব্যক্তিটি ম্যানচেস্টার সিটি পছন্দ করে, তবে তিনি সেই যাত্রীকে পছন্দনীয় চিকিত্সা ইত্যাদি দিতে পারেন he

  • কাউন্টারটি বিমানের শেষ প্রান্তে পৌঁছানো অবধি চলছে।

আইইনুমারেবলের সাথে এটি বেঁধে রাখি

  • একটি গণনাকারী একটি বিমানে যাত্রীদের কেবল সংগ্রহ। সিভিল এভিয়েশন আইন - এগুলি মূলত এমন নিয়ম যা সমস্ত আইয়ানমেন্টেবলদের অবশ্যই অনুসরণ করা উচিত। যতবার এয়ারলাইন্সের পরিচারক পাশের তথ্য নিয়ে ক্যাপ্টেনের কাছে যান, আমরা মূলত যাত্রীকে ক্যাপ্টেনের কাছে 'ফলদান' দিই। অধিনায়ক মূলত যাত্রীর সাথে যা খুশি তাই করতে পারেন - প্লেনে যাত্রীদের পুনরায় সাজানো ব্যতীত। এই ক্ষেত্রে, যদি তারা ম্যানচেস্টার সিটি অনুসরণ করে তবে তাদের অগ্রাধিকারমূলক চিকিত্সা দেওয়া হবে (উঘ!)

    foreach (Passenger passenger in Plane)
    // the airline hostess is now at the front of the plane
    // and slowly making her way towards the back
    // when she get to a particular passenger she gets some information
    // about the passenger and then immediately heads to the cabin
    // to let the captain decide what to do with it
    { // <---------- Note the curly bracket that is here.
        // we are now cockpit of the plane with the captain.
        // the captain wants to give the passenger free 
        // champaign if they support manchester city
        if (passenger.supports_mancestercity())
        {
            passenger.getFreeChampaign();
        } else
        {
            // you get nothing! GOOD DAY SIR!
        }
    } //  <---- Note the curly bracket that is here!
          the hostess has delivered the information 
          to the captain and goes to the next person
          on the plane (if she has not reached the 
          end of the plane)

সারসংক্ষেপ

অন্য কথায়, কোনও কিছুর একটি পাল্টা থাকলে গণনাযোগ্য । এবং কাউন্টার অবশ্যই (মূলত): (i) এর স্থান ( রাষ্ট্র ) মনে রাখবেন , (ii) পরবর্তী স্থানান্তর করতে সক্ষম হবেন , (iii) এবং তিনি যে বর্তমানের সাথে व्यवहार করছেন তার সম্পর্কে জানতে পারবেন ।

"গণনাযোগ্য" -এর জন্য অনুমিত কেবল অভিনব শব্দ। অন্য কথায়, একটি গণনাকারী আপনাকে 'গণনা' (অর্থাৎ গণনা) করতে দেয়।


23

আইনিম্যারেবল প্রয়োগসমূহ গেটইনুমরেটর। যখন ডাকা হয়, সেই পদ্ধতিটি একটি আইনিমরেটর ফিরিয়ে দেবে যা মুভনেেক্সট, রিসেট এবং বর্তমান প্রয়োগ করে।

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


18

আইনিউমেন্টেবল কার্যকর করা আপনাকে তালিকার জন্য একটি আইনিউমরেটর পেতে সক্ষম করে।

আইনিউমরেটর ফলনের কীওয়ার্ডটি ব্যবহার করে তালিকার আইটেমগুলিতে ফোরচ স্টাইলের ক্রমযুক্ত অ্যাক্সেসের অনুমতি দেয় allows

পূর্বে প্রয়োগের পূর্বে (উদাহরণস্বরূপ জাভা ১.৪-এ), তালিকাটি পুনরাবৃত্তি করার উপায়টি ছিল তালিকা থেকে একজন এনুমিরেটর নেওয়া, তারপরে তালিকার "পরবর্তী" আইটেমটির জন্য জিজ্ঞাসা করুন, যতক্ষণ পরবর্তী হিসাবে মান ফিরে আসবে আইটেম নাল নয়। লৌক () দৃশ্যের পিছনে মনিটর শ্রেণি প্রয়োগ করে, ঠিক একইভাবে ভাষা বৈশিষ্ট্যটি কেবল স্পষ্টভাবে কোনও ভাষা বৈশিষ্ট্য হিসাবে কাজ করে।

আমি প্রত্যাশা করি তালিকাগুলিতে কাজ করা কারণ তারা IEnumerable প্রয়োগ করে।


যদি এটি কোনও তালিকার জন্য থাকে তবে আমি কেন কেবল পূর্ববাচ ব্যবহার করতে পারি না?
prodev42

। নেট হাঁসটি ফোরচ স্টেটমেন্টটি টাইপ করে, তবে আইএননামেবল / আইনিউমেবল <T> আপনার ক্লাসটি গণনা করা যায় বলে উপযুক্ত উপায়।
ইউজার 7116

15
  • আইনিউমারেবল বাস্তবায়নকারী কোনও বস্তু অন্যকে তার প্রতিটি আইটেম (একজন গণকের দ্বারা) দেখার অনুমতি দেয়
  • আইমনামেটর বাস্তবায়নকারী কোনও বস্তু হ'ল পুনরাবৃত্তি। এটি একটি গণনাযোগ্য বস্তুর উপর লুপিং।

তালিকাগুলি, স্ট্যাকগুলি, গাছগুলি হিসাবে প্রচুর পরিমাণে বিবেচনা করুন।


12

IEnumerable এবং IEnumerator (এবং তাদের জেনেরিক প্রতিরূপ IEnumerable <টি> এবং IEnumerator <টি>) বেস ইন্টারফেসগুলি হয় পুনরুক্তিকারীর মধ্যে বাস্তবায়নের .NET Framework ক্লাস Libray সংগ্রহ

আপনি যে কোডটি বেশিরভাগ কোডের বাইরে দেখতে পাচ্ছেন তা হল সবচেয়ে সাধারণ ইন্টারফেস n এটি ফোরচ লুপ, জেনারেটর ( ফলন মনে করে ) সক্ষম করে এবং এর ক্ষুদ্রতর ইন্টারফেসের কারণে এটি শক্ত বিমূর্ততা তৈরি করতে ব্যবহৃত হয়। আইনিউমারেবল আইইনুমরেটরের উপর নির্ভর করে

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

IEnumerable

আইইনুমেবল হল একটি স্ট্যান্ডার্ড ইন্টারফেস যা এটি সমর্থন করে এমন সংগ্রহগুলির মাধ্যমে পুনরাবৃত্তি সক্ষম করে (বাস্তবে, আমি যে সমস্ত সংগ্রহের প্রকারের জন্য আমি আজ বিবেচনা করতে পারি সেগুলি IEnumerable প্রয়োগ করে )। সংকলক সমর্থন ভাষা বৈশিষ্ট্যগুলিকে পছন্দ করে foreach। সাধারণ পদগুলিতে, এটি এই অন্তর্নিহিত পুনরাবৃত্তি বাস্তবায়ন সক্ষম করে ।

foreach লুপ

foreach (var value in list)
  Console.WriteLine(value);

আমি মনে করি আইউনামেবল ইন্টারফেস foreachব্যবহারের অন্যতম প্রধান কারণ লুপ । লুপগুলির জন্য foreachক্লাসিক সি স্টাইলের তুলনায় খুব সংক্ষিপ্ত বাক্য গঠন এবং বুঝতে খুব সহজ যেখানে এটি কী করছে তা দেখার জন্য আপনাকে বিভিন্ন ভেরিয়েবল পরীক্ষা করতে হবে check

উত্স কীওয়ার্ড

সম্ভবত একটি কম পরিচিত বৈশিষ্ট্য হ'ল আইনিম্যারেবল সি ও # তে জেনারেটরyield return এবং yield breakস্টেটমেন্ট ব্যবহারের মাধ্যমে সক্ষম করে ।

IEnumerable<Thing> GetThings() {
   if (isNotReady) yield break;
   while (thereIsMore)
     yield return GetOneMoreThing();
}

abstractions

অনুশীলনে অন্য একটি সাধারণ দৃশ্যে ন্যূনতম বিমূর্ততা সরবরাহ করতে আইনিউমেবল ব্যবহার করা হয় । এটি একটি বিয়োগাত্মক এবং কেবল পঠনযোগ্য ইন্টারফেস হওয়ায় আপনাকে আপনার সংগ্রহগুলি আইইনামারেবল হিসাবে প্রকাশ করতে উত্সাহিত করা হবে ( উদাহরণস্বরূপ তালিকার চেয়ে )। এইভাবে আপনি আপনার ক্লায়েন্টের কোড না ভাঙিয়ে আপনার প্রয়োগ পরিবর্তন করতে মুক্ত হন ( উদাহরণস্বরূপ একটি লিঙ্কডলিস্টে তালিকা পরিবর্তন করুন )।

gotcha

সচেতন হওয়ার একটি আচরণ হ'ল স্ট্রিমিং বাস্তবায়নে (যেমন মেমোরিতে সমস্ত ফলাফল লোড করার পরিবর্তে কোনও ডাটাবেস থেকে সারি করে ডাটা সারি পুনরুদ্ধার করা) আপনি একাধিকবার সংগ্রহের মাধ্যমে পুনরাবৃত্তি করতে পারবেন না । এটি তালিকার মতো ইন-মেমরি সংগ্রহের বিপরীতে যেখানে আপনি সমস্যা ছাড়াই একাধিকবার পুনরাবৃত্তি করতে পারেন। উদাহরণস্বরূপ, রিশ্যার্পারের আইইনুমেবলের সম্ভাব্য একাধিক গণনার জন্য একটি কোড পরিদর্শন রয়েছে

IEnumerator

অন্যদিকে আইইনুমরেটর হল পর্দার ইন্টারফেসের পিছনে যা আইনুমারবল-ফোরচ-ম্যাজিক কাজ করে। কঠোরভাবে বলতে গেলে, এটি সুস্পষ্ট পুনরাবৃত্তিকে সক্ষম করে।

var iter = list.GetEnumerator();
while (iter.MoveNext())
    Console.WriteLine(iter.Current);

আমার অভিজ্ঞতায় আইমনুমেটর খুব বেশি ভার্বোস সিনট্যাক্স এবং সামান্য বিভ্রান্তিকর শব্দার্থবিজ্ঞানের কারণে খুব কমই সাধারণ পরিস্থিতিতে ব্যবহৃত হয় (কমপক্ষে আমার কাছে; উদাহরণস্বরূপ মুভনেক্সট () নামটিও দেয় না, যা নামটি মোটেই প্রস্তাব দেয় না)।

IEnumerator জন্য কেস ব্যবহার করুন

আমি কেবলমাত্র আইনিউমরেটর বিশেষত (কিছুটা নিম্ন স্তরের) লাইব্রেরি এবং ফ্রেমওয়ার্কগুলিতে ব্যবহার করেছি যেখানে আমি IEnumerable ইন্টারফেস সরবরাহ করছিলাম । একটি উদাহরণ হ'ল ডেটা স্ট্রিম প্রসেসিং লাইব্রেরি যা foreachবিভিন্ন ফাইল স্ট্রিম এবং সিরিয়ালাইজেশন ব্যবহার করে পর্দার আড়ালে ডেটা সংগ্রহ করা হলেও একটি লুপে সিরিজ অবজেক্ট সরবরাহ করে।

ক্লায়েন্ট কোড

foreach(var item in feed.GetItems())
    Console.WriteLine(item);

গ্রন্থাগার

IEnumerable GetItems() {
    return new FeedIterator(_fileNames)
}

class FeedIterator: IEnumerable {
    IEnumerator GetEnumerator() {
        return new FeedExplicitIterator(_stream);
    }
}

class FeedExplicitIterator: IEnumerator {
    DataItem _current;

    bool MoveNext() {
        _current = ReadMoreFromStream();
        return _current != null;           
    }

    DataItem Current() {
        return _current;   
    }
}

9

বাস্তবায়নকারী IEnumerableমূলত অর্থ হ'ল বস্তুটি পুনরাবৃত্তি হতে পারে। এর অর্থ এই নয় যে এটি একটি অ্যারে কারণ নির্দিষ্ট তালিকা রয়েছে যা সূচী করা যায় না তবে আপনি সেগুলি গণনা করতে পারেন।

IEnumeratorপুনরাবৃত্তি সম্পাদন করতে ব্যবহৃত প্রকৃত অবজেক্ট। এটি তালিকার এক বস্তু থেকে পরের দিকে যেতে নিয়ন্ত্রণ করে।

বেশিরভাগ সময়, IEnumerableএবং লুপের IEnumeratorঅংশ হিসাবে স্বচ্ছভাবে ব্যবহৃত হয় foreach


6

আইনিউমারেবল এবং আইনিউমরেটরের মধ্যে পার্থক্য:

  • আইনিম্যারেবল অভ্যন্তরীণভাবে আইনিমরেটর ব্যবহার করে।
  • আইনিউমারেবল জানেন না কোন আইটেম / অবজেক্টটি কার্যকর করছে।
  • যখনই আমরা আইনিমরেটরটিকে অন্য কোনও ফাংশনে পাস করি, এটি আইটেম / অবজেক্টের বর্তমান অবস্থানটি জানে।
  • আমরা যখনই কোনও কার্যক্রমে একটি মূল সংগ্রহটি পাস করি তখন এটি আইটেম / অবজেক্টের বর্তমান অবস্থানটি জানে না (কোন আইটেমটি এটি সম্পাদন করে তা জানে না)

    গণনাকারীদের একটি পদ্ধতি গেটইনুমরেটর রয়েছে ()

public interface IEnumerable<out T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}

আইইনুমরেটরের কারেন্ট নামে দুটি সম্পত্তি রয়েছে এবং দুটি পদ্ধতি রিসেট () এবং মুভনেেক্সট () যা তালিকার কোনও আইটেমের বর্তমান অবস্থান জানার জন্য দরকারী)।

public interface IEnumerator
{
     object Current { get; }
     bool MoveNext();
     void Reset();
}

5

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

public class Customer
{
    public String Name { get; set; }
    public String City { get; set; }
    public long Mobile { get; set; }
    public double Amount { get; set; }
}

এখন আমরা ক্লাসটি সংজ্ঞায়িত করব যা আমাদের ক্লাস গ্রাহকের জন্য সংগ্রহ হিসাবে কাজ করবে। লক্ষ্য করুন যে এটি ইন্টারফেসটি IEnumerable প্রয়োগ করছে। যাতে আমাদের getEnumerator পদ্ধতিটি প্রয়োগ করতে হবে। এটি আমাদের কাস্টম এনুমरेटरকে ফিরিয়ে দেবে।

public class CustomerList : IEnumerable
{
    Customer[] customers = new Customer[4];
    public CustomerList()
    {
        customers[0] = new Customer { Name = "Bijay Thapa", City = "LA", Mobile = 9841639665, Amount = 89.45 };
        customers[1] = new Customer { Name = "Jack", City = "NYC", Mobile = 9175869002, Amount = 426.00 };
        customers[2] = new Customer { Name = "Anil min", City = "Kathmandu", Mobile = 9173694005, Amount = 5896.20 };
        customers[3] = new Customer { Name = "Jim sin", City = "Delhi", Mobile = 64214556002, Amount = 596.20 };
    }

    public int Count()
    {
        return customers.Count();
    }
    public Customer this[int index]
    {
        get
        {
            return customers[index];
        }
    }
    public IEnumerator GetEnumerator()
    {
        return customers.GetEnumerator(); // we can do this but we are going to make our own Enumerator
        return new CustomerEnumerator(this);
    }
}

এখন আমরা নিম্নলিখিত হিসাবে আমাদের নিজস্ব কাস্টম এনুমুলেটর তৈরি করতে যাচ্ছি। সুতরাং, আমাদের পদ্ধতি মুভনেেক্সট বাস্তবায়ন করতে হবে।

 public class CustomerEnumerator : IEnumerator
    {
        CustomerList coll;
        Customer CurrentCustomer;
        int currentIndex;
        public CustomerEnumerator(CustomerList customerList)
        {
            coll = customerList;
            currentIndex = -1;
        }

        public object Current => CurrentCustomer;

        public bool MoveNext()
        {
            if ((currentIndex++) >= coll.Count() - 1)
                return false;
            else
                CurrentCustomer = coll[currentIndex];
            return true;
        }

        public void Reset()
        {
            // we dont have to implement this method.
        }
    }

এখন আমরা নীচের মত আমাদের সংগ্রহে ফোরচ লুপ ব্যবহার করতে পারি;

    class EnumeratorExample
    {
        static void Main(String[] args)
        {

            CustomerList custList = new CustomerList();
            foreach (Customer cust in custList)
            {
                Console.WriteLine("Customer Name:"+cust.Name + " City Name:" + cust.City + " Mobile Number:" + cust.Amount);
            }
            Console.Read();

        }
    }

4

Iterator প্যাটার্ন একটি বোঝা আপনার জন্য সহায়ক হবে। আমি একই পড়া সুপারিশ।

Iterator প্যাটার্ন

একটি উচ্চ স্তরে পুনরাবৃত্তি প্যাটার্নটি কোনও ধরণের সংগ্রহের মাধ্যমে পুনরাবৃত্তির একটি মানক উপায় সরবরাহ করতে ব্যবহার করা যেতে পারে। আমাদের পুনরাবৃত্তি প্যাটার্নে প্রকৃত সংগ্রহ (ক্লায়েন্ট), একগ্রিগেটর এবং পুনরুক্তকারীতে 3 জন অংশগ্রহনকারী রয়েছে। সমষ্টিগত একটি ইন্টারফেস / বিমূর্ত শ্রেণি যা একটি পদ্ধতি যা একটি পুনরাবৃত্তিকে ফেরত দেয়। Iterator হল একটি ইন্টারফেস / বিমূর্ত শ্রেণি যা পদ্ধতিতে আমাদের সংগ্রহের মাধ্যমে পুনরাবৃত্তি করতে দেয়।

প্যাটার্নটি বাস্তবায়নের জন্য প্রথমে একটি কংক্রিট তৈরির জন্য একটি ইেটরেটর প্রয়োগ করা দরকার যা সংশ্লিষ্ট সংগ্রহের উপরে পুনরাবৃত্তি করতে পারে (ক্লায়েন্ট) তারপরে সংগ্রহ (ক্লায়েন্ট) উপরোক্ত পুনরুক্তির কোনও উদাহরণ ফেরত দেওয়ার জন্য সমষ্টিকে প্রয়োগ করে।

এখানে ইউএমএল চিত্রটি রয়েছে Iterator প্যাটার্ন

সুতরাং মূলত সি # তে, আইমেনিউরেবল হ'ল বিমূর্ত সমষ্টি এবং আইইনুমেটর হ'ল বিমূর্ত Iterator। আইনিউমারেবলের একটি একক পদ্ধতি গেটইনিউমরেটর থাকে যা পছন্দসই ধরণের আইনিমরেটর তৈরির জন্য দায়ী। তালিকার মতো সংগ্রহগুলি আইকনামেবল প্রয়োগ করে।

উদাহরণ। ধরা যাক আমাদের একটি পদ্ধতি আছেgetPermutations(inputString) যা একটি স্ট্রিংয়ের সমস্ত ক্রিয়াকলাপ দেয় এবং পদ্ধতিটি একটি উদাহরণ দেয় returnsIEnumerable<string>

ক্রমের সংখ্যা গণনা করার জন্য আমরা নীচের মতো কিছু করতে পারি।

 int count = 0;
        var permutations = perm.getPermutations(inputString);
        foreach (string permutation in permutations)
        {
            count++;
        }

সি # সংকলক কমবেশি উপরের দিকে রূপান্তর করে

using (var permutationIterator = perm.getPermutations(input).GetEnumerator())
        {
            while (permutationIterator.MoveNext())
            {
                count++;
            }
        }

আপনার যদি কোনও প্রশ্ন থাকে তবে জিজ্ঞাসা করতে দ্বিধা করবেন না।


2

একটি ছোট অবদান।

তাদের মধ্যে অনেকে 'কখন ব্যবহার করবেন' এবং 'পূর্বাভাসের সাথে ব্যবহার' সম্পর্কে ব্যাখ্যা করেছেন। আমি অন্য রাজ্যের পার্থক্য যুক্ত করার কথা ভেবেছিলামআইইনিউমারেবল আইইনুমরেটর উভয়ের মধ্যে পার্থক্য সম্পর্কে অনুরোধ করাতে এখানে ।

আমি নীচের আলোচনার থ্রেডের উপর ভিত্তি করে নীচের কোড নমুনা তৈরি করেছি।

আইনিউমারেবল, আইইনুমরেটর বনাম ফোরচ, কখন ব্যবহার করবেন আইইনুমরেটর এবং আইনুমেবলের মধ্যে পার্থক্য কী?

গণক ফাংশন কলগুলির মধ্যে রাষ্ট্রের (পুনরাবৃত্তির অবস্থান) সংরক্ষণ করে যখন অন্যদিকে পুনরাবৃত্তি গণনাযোগ্য নয়।

এখানে মন্তব্যগুলি বোঝার জন্য পরীক্ষিত উদাহরণ।

বিশেষজ্ঞরা দয়া করে আমাকে যুক্ত / সংশোধন করুন।

static void EnumerableVsEnumeratorStateTest()
{
    IList<int> numList = new List<int>();

    numList.Add(1);
    numList.Add(2);
    numList.Add(3);
    numList.Add(4);
    numList.Add(5);
    numList.Add(6);

    Console.WriteLine("Using Enumerator - Remembers the state");
    IterateFrom1to3(numList.GetEnumerator());

    Console.WriteLine("Using Enumerable - Does not Remembers the state");
    IterateFrom1to3Eb(numList);

    Console.WriteLine("Using Enumerable - 2nd functions start from the item 1 in the collection");
}

static void IterateFrom1to3(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());

        if (numColl.Current > 3)
        {
            // This method called 3 times for 3 items (4,5,6) in the collection. 
            // It remembers the state and displays the continued values.
            IterateFrom3to6(numColl);
        }
    }
}

static void IterateFrom3to6(IEnumerator<int> numColl)
{
    while (numColl.MoveNext())
    {
        Console.WriteLine(numColl.Current.ToString());
    }
}

static void IterateFrom1to3Eb(IEnumerable<int> numColl)
{
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());

        if (num>= 5)
        {
            // The below method invokes for the last 2 items.
            //Since it doesnot persists the state it will displays entire collection 2 times.
            IterateFrom3to6Eb(numColl);
        }
    }
}

static void IterateFrom3to6Eb(IEnumerable<int> numColl)
{
    Console.WriteLine();
    foreach (int num in numColl)
    {
        Console.WriteLine(num.ToString());
    }
}

2

আমি এই পার্থক্যগুলি লক্ষ্য করেছি:

উ: আমরা তালিকাটিকে বিভিন্ন উপায়ে পুনরাবৃত্তি করি, পূর্বাঞ্চ আইইনুমেবলের জন্য এবং আইনুমরেটরের জন্য লুপ ব্যবহার করা যেতে পারে।

বি। আইনিউমরেটর বর্তমান সূচকটি স্মরণ করতে পারে যখন আমরা একটি পদ্ধতি থেকে অন্য পদ্ধতিতে চলে যাই (এটি বর্তমান সূচকের সাথে কাজ করা শুরু করে) তবে আইনামিউরেবল সূচকটি মনে করতে পারে না এবং এটি সূচকটি শুরুতে পুনরায় সেট করে। এই ভিডিওটিতে আরও https://www.youtube.com/watch?v=jd3yUjGc9M0


1

IEnumerableএবং IEnumeratorউভয়ই সি # তে ইন্টারফেস।

IEnumerableএকটি ইন্টারফেস যা একটি একক পদ্ধতি সংজ্ঞা GetEnumerator()দেয় যা একটি IEnumeratorইন্টারফেস দেয়।

এটি কোনও সংগ্রহের পাঠ্য-কেবল অ্যাক্সেসের জন্য কাজ করে যা কার্যকর করে যা বিবৃতি IEnumerableদিয়ে ব্যবহার করা যেতে পারে foreach

IEnumeratorদুটি পদ্ধতি আছে, MoveNextএবং Reset। এটি একটি সম্পত্তি বলা হয়Current

নীচে আইইনিউমারেবল এবং আইনিউমরেটর বাস্তবায়ন দেখায়।


0
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Enudemo
{

    class Person
    {
        string name = "";
        int roll;

        public Person(string name, int roll)
        {
            this.name = name;
            this.roll = roll;
        }

        public override string ToString()
        {
            return string.Format("Name : " + name + "\t Roll : " + roll);
        }

    }


    class Demo : IEnumerable
    {
        ArrayList list1 = new ArrayList();

        public Demo()
        {
            list1.Add(new Person("Shahriar", 332));
            list1.Add(new Person("Sujon", 333));
            list1.Add(new Person("Sumona", 334));
            list1.Add(new Person("Shakil", 335));
            list1.Add(new Person("Shruti", 336));
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
           return list1.GetEnumerator();
        }
    }



    class Program
    {
        static void Main(string[] args)
        {
            Demo d = new Demo();  // Notice here. it is simple object but for 
                                //IEnumerator you can get the collection data

            foreach (Person X in d)
            {
                Console.WriteLine(X);
            }

            Console.ReadKey();
        }
    }
}
/*
Output : 

Name : Shahriar  Roll : 332
Name : Sujon     Roll : 333
Name : Sumona    Roll : 334
Name : Shakil    Roll : 335
Name : Shruti    Roll : 336
  */
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.