Visual C# sınıfını foreach deyiminde kullanılabilir hale getirme

Bu makalede, deyimde kullanabileceğiniz IEnumerable bir sınıf oluşturmak için ve IEnumerator arabirimlerinin nasıl kullanılacağı foreach gösterilmektedir.

Özgün ürün sürümü: Visual Studio
Özgün KB numarası: 322022

IEnumerator arabirimi

IEnumerable ve IEnumerator sık sık birlikte kullanılır. Bu arabirimler benzer olsa da (ve benzer adlara sahip olsalar da), farklı amaçları vardır.

Arabirimi, IEnumerator bir sınıfın iç koleksiyonu için yinelemeli özellik sağlar. IEnumerator üç yöntem uygulamanızı gerektirir:

  • Yöntemi MoveNext , koleksiyon dizinini 1 artırır ve koleksiyonun sonuna ulaşılıp ulaşılmadığını gösteren bir bool döndürür.

  • Reset Koleksiyon dizinini -1 başlangıç değerine sıfırlayan yöntemi. Bu, numaralandırıcıyı geçersiz klenir.

  • konumundaki Current geçerli nesneyi positiondöndüren yöntemi.

    public bool MoveNext()
    {
        position++;
        return (position < carlist.Length);
    }
    public void Reset()
    {
        position = -1;
    }
    public object Current
    {
        get { return carlist[position];}
    }
    

IEnumerable arabirimi

Arabirimi IEnumerable yineleme için foreach destek sağlar. IEnumerable yöntemini uygulamanız GetEnumerator gerekir.

public IEnumerator GetEnumerator()
{
    return (IEnumerator)this;
}

Hangi arabirimin kullanılacağı

Başlangıçta, bu arabirimleri kullanmayı kafa karıştırıcı bulabilirsiniz. Arabirimi, IEnumerator bir sınıftaki koleksiyon türündeki bir nesne üzerinde yineleme sağlar. Arabirimi bir IEnumerable döngü kullanarak foreach numaralandırmaya izin verir. Ancak, GetEnumerator arabiriminin IEnumerable yöntemi bir IEnumerator arabirim döndürür. Bu nedenle uygulamak IEnumerableiçin de uygulamanız IEnumeratorgerekir. uygulamazsanız IEnumerator, yönteminden GetEnumeratorIEnumerable dönüş değerini arabirimine IEnumerator atamazsınız.

Özetle, kullanımı IEnumerable sınıfının uygulamasını IEnumeratorgerektirir. için foreachdestek sağlamak istiyorsanız her iki arabirimi de uygulayın.

Adım adım örnek

Aşağıdaki örnekte bu arabirimlerin nasıl kullanılacağı gösterilmektedir. Bu örnekte ve IEnumeratorIEnumerable arabirimleri adlı carsbir sınıfta kullanılır. sınıfı cars bir iç nesne dizisine car sahiptir. İstemci uygulamaları, bu iki arabirimin uygulanması nedeniyle bir foreach yapı kullanarak bu iç diziyi numaralandırabilir.

  1. Visual C# içinde yeni bir Konsol Uygulaması projesi oluşturmak için şu adımları izleyin:

    1. Microsoft Visual Studio .NET veya Visual Studio'yu başlatın.
    2. Dosya menüsünde, Yeni'nin üzerine gelin ve Proje'ye tıklayın.
    3. Proje Türleri altında Visual C# Projeleri'ne tıklayın ve ardından Şablonlar altında Konsol Uygulaması seçeneğine tıklayın.
    4. Ad kutusuna ConsoleEnum yazın.
  2. Class1.cshost.cs olarak yeniden adlandırın ve host.cs kodu aşağıdaki kodla değiştirin:

    using System;
    namespace ConsoleEnum
    {
       class host
       {
           [STAThread]
           static void Main(string[] args)
           {
               cars C = new cars();
               Console.WriteLine("\nInternal Collection (Unsorted - IEnumerable,Enumerator)\n");
               foreach(car c in C)
               Console.WriteLine(c.Make + "\t\t" + c.Year);
               Console.ReadLine();
           }
       }
    }
    
  3. Proje menüsünde Sınıf Ekle'ye tıklayın ve Ad kutusuna araba yazın.

  4. car.cs içindeki kodu aşağıdaki kodla değiştirin:

    using System;
    using System.Collections;
    namespace ConsoleEnum
    {
       public class car
       {
           private int year;
           private string make;
           public car(string Make,int Year)
           {
               make=Make;
               year=Year;
           }
           public int Year
           {
               get  {return year;}
               set {year=value;}
           }
           public string Make
           {
               get {return make;}
               set {make=value;}
           }
       }//end class
    }//end namespace
    
  5. Proje menüsünde Sınıf Ekle'ye tıklayarak projeye başka bir sınıf ekleyin ve ardından Ad kutusuna arabalar yazın.

  6. cars.cs içindeki kodu aşağıdaki kodla değiştirin:

    using System;
    using System.Collections;
    namespace ConsoleEnum
    {
        public class cars : IEnumerator,IEnumerable
        {
           private car[] carlist;
           int position = -1;
           //Create internal array in constructor.
           public cars()
           {
               carlist= new car[6]
               {
                   new car("Ford",1992),
                   new car("Fiat",1988),
                   new car("Buick",1932),
                   new car("Ford",1932),
                   new car("Dodge",1999),
                   new car("Honda",1977)
               };
           }
           //IEnumerator and IEnumerable require these methods.
           public IEnumerator GetEnumerator()
           {
               return (IEnumerator)this;
           }
           //IEnumerator
           public bool MoveNext()
           {
               position++;
               return (position < carlist.Length);
           }
           //IEnumerable
           public void Reset()
           {
               position = -1;
           }
           //IEnumerable
           public object Current
           {
               get { return carlist[position];}
           }
        }
      }
    
  7. Projeyi çalıştırın.

Konsol penceresinde aşağıdaki çıkış görüntülenir:

Ford            1992
Fiat            1988
Buick           1932
Ford            1932
Dodge           1999
Honda           1977

En iyi uygulamalar

Bu makaledeki örnek, bu arabirimlerin kullanımını daha iyi açıklamak için olabildiğince basit tutulur. Kodu daha sağlam hale getirmek ve kodun geçerli en iyi yöntem yönergelerini kullandığından emin olmak için kodu aşağıdaki gibi değiştirin:

  • Birden çok numaralandırıcı oluşturabilmek için iç içe geçmiş bir sınıfta uygulayın IEnumerator .
  • yöntemi için Current özel durum işleme sağlayın IEnumerator. Koleksiyonun içeriği değişirse yöntemi reset çağrılır. Sonuç olarak, geçerli numaralandırıcı geçersiz kılındı ve bir IndexOutOfRangeException özel durum alırsınız. Diğer koşullar da bu özel duruma neden olabilir. Bu nedenle, bu özel durumu yakalamak ve bir Try...Catch özel durum oluşturmak için bir InvalidOperationException blok uygulayın.
using System;
using System.Collections;
namespace ConsoleEnum
{
    public class cars : IEnumerable
    {
        private car[] carlist;
  
        //Create internal array in constructor.
        public cars()
        {
            carlist= new car[6]
            {
                new car("Ford",1992),
                new car("Fiat",1988),
                new car("Buick",1932),
                new car("Ford",1932),
                new car("Dodge",1999),
                new car("Honda",1977)
            };
        }
        //private enumerator class
        private class  MyEnumerator:IEnumerator
        {
            public car[] carlist;
            int position = -1;

            //constructor
            public MyEnumerator(car[] list)
            {
                carlist=list;
            }
            private IEnumerator getEnumerator()
            {
                return (IEnumerator)this;
            }
            //IEnumerator
            public bool MoveNext()
            {
                position++;
                return (position < carlist.Length);
            }
            //IEnumerator
            public void Reset()
            {
                position = -1;
            }
            //IEnumerator
            public object Current
            {
                get
                {
                    try
                    {
                        return carlist[position];
                    }
                    catch (IndexOutOfRangeException)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }
        }  //end nested class
      public IEnumerator GetEnumerator()
      {
          return new MyEnumerator(carlist);
      }
    }
}