【C#】IEnumerableの使い方

IEnumerableとは

「IEnumerable」とは、C#の標準機能として使用できるインターフェースの1つです(Enumerableとは列挙可能という意味の英語です)。

■公式ドキュメント
https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.ienumerable?view=net-5.0

List、Stack、Queueといったコレクションのクラスに実装されており、それらのクラスから反復処理をする「IEnumerator」を実装したクラスインスタンスを取得することができます。

また、IEnumerableを自作クラス(カスタムクラス)に実装することで、Listクラスなどと同様にIEnumeratorを取得して反復処理ができるようになります(非ジェネリックコレクションに対する単純な反復処理をサポートする列挙子を公開します。)。

 

Listを使ったサンプルコード

Listのサンプルコード

using System;
using System.Collections.Generic;

namespace c_inumerable
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List() { "自動車", "バイク", "自転車" };

            foreach (string vehicle in list)
            {
                Console.WriteLine(vehicle);
            }
        }
    }
}

実行結果:

自動車
バイク
自転車

Listクラスをforeachで表示しました。

 

IEnumerableのサンプルコード

上記のサンプルコードをIEnumerableを使って以下のようにすることも可能です。

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

namespace c_inumerable
{
    class Program
    {
        static void Main(string[] args)
        {
            var list = new List() { "自動車", "バイク", "自転車" };

            IEnumerable enumerable = list; // listをIEnumerableにキャスト(List型はIEnumerableを実装しているため可能)

            IEnumerator enumerator = enumerable.GetEnumerator(); // GetEnumeratorメソッドでIEnumeratorを実装したインスタンスを取り出す

            while (enumerator.MoveNext()) // IEnumeratorのMoveNextメソッドとCurrentプロパティで中身を表示する処理を実行
            {
                Console.WriteLine(enumerator.Current);
            }
        }
    }
} 

実行結果:

自動車
バイク
自転車

上記のように、実行結果は先ほどと同じになります。

「MoveNext」は、データのリストのインデックスを移動して、中身がある場合はtrueを返します。

「Current」は、現在のインデックスの中身を返します。

 

カスタムクラスを使ったサンプルコード

IEnumerableは、実際の開発現場においてカスタムクラスをforeachなどで使えるようにしたい場合に使用することが多いです

using System;
using System.Collections;

namespace c_inumerable
{
    class Car
    {
        private string _carMaker; // 車のメーカー
        private string _carModel; // 車種
        private int _salesQuantity; // 販売台数

        public Car(string carMaker, string carModel, int salesQuantity)  // 完全コンストラクタパターン
        {
            _carMaker = carMaker;
            _carModel = carModel;
            _salesQuantity = salesQuantity;
        }
        
        public override string ToString()
        {
            return $"{_carMaker}で最も売れている車は、{_carModel}で2021年3月の販売台数は{_salesQuantity}台です。";
        }
    }

    class Cars : IEnumerable, IEnumerator
    {
        ArrayList carList = new ArrayList();

        public void AddCar(Car car)
        {
            carList.Add(car);
        }

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

        private int CurrentPosition = -1;

        public bool MoveNext()
        {
            if (CurrentPosition < carList.Count - 1)
            {
                ++CurrentPosition;

                return true;
            }
            return false;
        }

        public void Reset()
        {
            CurrentPosition = -1;
        }
        
        public object Current
        {
            get
            {
                return carList[CurrentPosition];
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Cars carsList = new Cars();

            Car car1 = new Car("トヨタ", "ヤリス", 28466);
            Car car2 = new Car("日産", "ノート", 13352);

            carsList.AddCar(car1);
            carsList.AddCar(car2);

            foreach (Car car in carsList)
            {
                Console.WriteLine(car);
            }
        }
    }
}

実行結果:

トヨタで最も売れている車は、ヤリスで2021年3月の販売台数は28466台です。
日産で最も売れている車は、ノートで2021年3月の販売台数は13352台です。

上記のように、独自の機能を追加したカスタムクラスで「foreach」を使用したい場合は、「IEnumerable」が必要になります。

 

おすすめ・参考書籍

■C#を学習し始めた方向け
やさしいC 第3版 (「やさしい」シリーズ)

1週間でCの基礎が学べる本

確かな力が身につくC「超」入門 第2版 (Informatics&IDEA)

■C#をある程度学習した方向け
基礎からしっかり学ぶCの教科書 改訂新版 (マイクロソフト関連書)

独習C 新版

Effective C 6.0/7.0