Yield は、スペースを節約できるので便利です。プログラミングのほとんどの最適化では、スペース (ディスク、メモリ、ネットワーク) と処理の間でトレードオフが行われます。プログラミング構造としての Yield を使用すると、繰り返しごとにコレクションの個別のコピーを必要とせずに、コレクションを順番に何度も繰り返すことができます。
次の例を検討してください。
static IEnumerable<Person> GetAllPeople()
{
return new List<Person>()
{
new Person() { Name = "George", Surname = "Bush", City = "Washington" },
new Person() { Name = "Abraham", Surname = "Lincoln", City = "Washington" },
new Person() { Name = "Joe", Surname = "Average", City = "New York" }
};
}
static IEnumerable<Person> GetPeopleFrom(this IEnumerable<Person> people, string where)
{
foreach (var person in people)
{
if (person.City == where) yield return person;
}
yield break;
}
static IEnumerable<Person> GetPeopleWithInitial(this IEnumerable<Person> people, string initial)
{
foreach (var person in people)
{
if (person.Name.StartsWith(initial)) yield return person;
}
yield break;
}
static void Main(string[] args)
{
var people = GetAllPeople();
foreach (var p in people.GetPeopleFrom("Washington"))
{
// do something with washingtonites
}
foreach (var p in people.GetPeopleWithInitial("G"))
{
// do something with people with initial G
}
foreach (var p in people.GetPeopleWithInitial("P").GetPeopleFrom("New York"))
{
// etc
}
}
(明らかに、拡張メソッドで yield を使用する必要はありません。データについて考えるための強力なパラダイムを作成するだけです。)
ご覧のとおり、これらの「フィルター」メソッドが多数ある場合 (ただし、人のリストに対してなんらかの作業を行う任意の種類のメソッドである可能性があります)、ステップごとに余分なストレージ スペースを必要とせずに、それらの多くを連鎖させることができます。 . これは、ソリューションをより適切に表現するためにプログラミング言語 (C#) を向上させる 1 つの方法です。
yield の最初の副作用は、実際に必要になるまでフィルタリング ロジックの実行を遅らせることです。したがって、タイプ IEnumerable<> の変数を (yield を使用して) 作成しても、それを反復処理しない場合、ロジックを実行したり、スペースを消費したりすることはありません。これは、強力で無料の最適化です。
もう 1 つの副作用は、yield が最も一般的なコレクション インターフェイス (IEnumerable<>) で動作することです。これにより、幅広い適用性を持つライブラリのようなコードを作成できます。