C#のyield returnで出来ることは?簡単なサンプルや有効活用法までご紹介

- システム
エンジニア - C#のyield returnはどのようなことが出来るのでしょうか。
- プロジェクト
マネージャー - コレクションを順次返却できたり、記述が簡潔になります。
C#のyield returnとは?
C#のreturnについて知っている人は多いと思われますが、yield returnについては知らない人も多いのではないでしょうか。yield returnを活用すると複数のデータを扱う場合に効率的なプログラムを記述することができます。
yield returnとreturnの大きな違いは、returnは呼ばれると実行中のメソッドからすぐに抜けて呼び出し元に戻りますが、yield returnは戻らずに値のみを返すという点です。これからyield returnを実例で説明しますので、是非マスターしてください。
yield returnの簡単なサンプル
以下はyield returnのC#サンプルです。なおソースの先頭に「using System;」「using System.Collections.Generic;」を記述してください。1つ目はVisual Studioの場合は最初から入っています。
static IEnumerable<int> OneToTen()
{
for (int i = 1; i <= 10; i++)
{
yield return i;
}
}
static void Main(string[] args)
{
foreach (int num in OneToTen())
{
Console.Write(num + ” “);
}
}
yield returnでコレクションを順次返却できる
上のC#のサンプルを実行すると、以下のように表示されます。
1 2 3 4 5 6 7 8 9 10
yield returnはコレクション(IEnumerable)の形式で、メソッドから抜けずに値を順次、返すことができるのです。なおOneToTenクラスは以下のように記述しても全く同じ動作をします。
static IEnumerable<int> OneToTen()
{
var l = new List<int>();
for (int i = 1; i <= 10; i++)
{
l.Add(i);
}
return l;
}
yield returnを使えば記述が簡潔になる
2つ目のサンプルのOneToTenのように記述してもかまいませんが、yield returnを使用すれば返却するために一時的にListを生成する必要がありません。yield returnでスマートな記述が可能になります。
yield returnを使う場合、もう一つ理解しておくことがあります。以下のC#のサンプルを見てください。
static IEnumerable<int> OneToFive()
{
yield return 1;
yield return 2;
yield return 3;
//yield returnを中止したい
return;
yield return 4;
yield return 5;
}
static void Main(string[] args)
{
foreach (int num in OneToFive())
{
Console.Write(num + ” “);
}
}
yield returnの中断にはyield breakを使用する
上のようにyield returnを途中でやめたい場合はどうすればいいのでしょうか。上のようにreturn;を記述しても、IEnumerable<int>の値を返していないためエラーになります。return 0;のようにしても同様です。break;でもやはりエラーです。
こういった時は以下のようにyield breakを使用します。
static IEnumerable<int> OneToFive()
{
yield return 1;
yield return 2;
yield return 3;
//yield returnを中止したい
yield break;
yield return 4;
yield return 5;
}
ループ処理ではない時の中断はyield break
上のC#のサンプルを実行すると、以下のように表示されます。yield breakにより中断されています。
1 2 3
最初のOneToTenのようにforループでyield returnをしている場合、中断したい時はbreakで止められます。しかし今回のOneToFiveのようにループ処理ではない場合は、中断するためにyield breakが必要になります。yield returnとセットで覚えておきましょう。
yield returnの有効活用
ここまでのC#サンプルを見て、yield returnがあまり役に立つように感じないかもしれません。単純な処理であればList型のローカル変数にAddしていって返す、という方法でもいいでしょう。
しかしyield returnが有効なケースもあり、その一つが再帰処理です。以下のサンプルをご覧ください。なお実行する場合はソースの先頭に「using System.IO;」を追加してください。
static IEnumerable<string> GetFileNames(string folder)
{
string[] files = Directory.GetFiles(folder); // ファイル一覧を取得
foreach(string fi in files)
{
yield return fi; // ファイル名を返す
}
string[] folders = Directory.GetDirectories(folder); // フォルダ一覧を取得
foreach(string fo in folders)
{
foreach (string fi in GetFileNames(fo)) // 自分自身をコール
{
yield return fi; // フォルダ内のファイル名を返す
}
}
}
static void Main(string[] args)
{
foreach (string str in GetFileNames(“c:\\test”))
{
Console.WriteLine(str);
}
}
再帰処理でyield returnを利用する
上のC#サンプルのGetFileNamesメソッドは、ツリー構造になっているフォルダ内のファイルの一覧を全て表示します。呼ばれると、まずDirectory.GetFilesで現在の階層の全てのファイル一覧をyield returnで返します。
次にDirectory.GetDirectoriesで現在の階層の全てのフォルダ一覧を取得し、各フォルダをパラメータとして、自分自身であるGetFileNamesを呼び出します。このような作り方を再帰処理と言います。
再帰処理ではyield returnを有効活用できる
自分自身のGetFileNamesを呼び出す再帰処理では、下の階層のファイル一覧を取得できます。それをyield returnで呼び出し元に返します。まるでバケツリレーのように、下の階層の情報が上に向かってハンドリングされていくのです。
そして最初にGetFileNamesを呼び出したMainメソッドに、各階層のすべてのファイル一覧が届きます。ここでは一括でそれを表示できるのです。実行結果は以下のようになります(結果はtestフォルダ内の状況によります)。
c:\test\a.txt
c:\test\b.png
c:\test\test2\c.txt
c:\test\test2\test3\d.txt
yield returnで再帰処理が綺麗な構造になる
上のような再帰処理でyield returnを使わず、別に用意したListに次々にAddして、最後にそれを表示するというやり方も、もちろん可能です。ただそれよりもこのサンプルのように内部だけで完結している方が、汎用性の高いプログラムと言えます。
yield returnが無い他の言語からC#を始める人には、yield returnを使用しない方がわかりやすいのは確かですが、C#の機能を活用してプログラムする方がベターです。
- システム
エンジニア - 再帰処理でyield returnが有効活用できるのですね。
- プロジェクト
マネージャー - yield returnを使うと内部だけで完結するので、汎用性の高いプログラムと言えるでしょう。
yield returnを活用してC#らしさを発揮しよう
yield returnについて解説しましたがいかがでしたでしょうか。yield returnは他のやり方でも代用できる機能ではありますが、上手く利用すればC#らしいプログラムを記述することができます。yield returnを積極的に活用しましょう。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社夢真ビーネックスグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅) -
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)