Meiryo’s blog

やってみて詰まったことを備忘録として残すブログ

【C#】Listのインスタンスを生成させずに要素を返すメソッドの作り方

今までList型を返すメソッドを書く時、
メソッドの中でインスタンスを作って返していたのですが
yieldを使うとインスタンスを作らなくて
良くなるということを知ったので紹介します。

今まで書いていたコード

using System;
using System.Collections.Generic;

public class Test
{
    public static void Main(string[] args)
    {
        var t = new Test();
        var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        var evenList = t.GetEven(list);

        foreach (var v in evenList)
        {
            Console.WriteLine(v);
        }
    }

    //偶数のみを返す
    public List<int> GetEven(List<int> list)
    {
        var temp = new List<int>();
        foreach (var v in list)
        {
            if (v % 2 == 0)
            {
                temp.Add(v);
            }
        }
        return temp;
    }
}

GetEvenは引数に渡されたListの中から
偶数のみを取り出し、返すメソッドです。
メソッド内でListのインスタンスを作って
該当する値を格納していますが
yieldを使うとListを作らずに済むようになります。

yieldを使った場合

using System;
using System.Collections.Generic;

public class Test
{
    public static void Main(string[] args)
    {
        var t = new Test();
        var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        foreach (var v in t.GetEven(list))
        {
            Console.WriteLine(v);
        }
    }

    //偶数のみを返す
    public IEnumerable<int> GetEven(List<int> list)
    {
        foreach (var v in list)
        {
            if (v % 2 == 0)
            {
                yield return v;
            }
        }
    }
}

Listを作っている部分がなくなり、
コードが少しすっきりしました。

あと多分ですけど、巨大なファイルを
読み込んだ時とかにListで抱えなくて
済むようになったので
なんか良いことあるはずですが
今の所断定できることがないので
なにかわかったら追記します。

おまけ

メソッドの引数の型を変えることで
配列にも対応できたりする

using System;
using System.Collections.Generic;

public class Test
{
    public static void Main(string[] args)
    {
        var t = new Test();
        var list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        var array = list.ToArray();

        foreach (var v in t.GetEven(array))
        {
            Console.WriteLine(v);
        }
    }

    //偶数のみを返す
    public IEnumerable<int> GetEven(IEnumerable<int> list)
    {
        foreach (var v in list)
        {
            if (v % 2 == 0)
            {
                yield return v;
            }
        }
    }
}