C#のyieldを甘く見てました
VBばかり見ていたせいでC#のyieldのすごさを見逃していました。
C# 2.0でyieldが登場した時は、「簡単に列挙できて便利だなぁ、VBにもあればいいなぁ、でもなくてもなんとかなるからしばらくは我慢するかぁ」くらいに思っていたのですが、最近知りました。
yeild returnで返すメソッドは遅延評価されるって皆さんご存知でしたか?(このようなメソッドをサブルーチンではなく『コルーチン』と呼ぶらしいです。)
たとえば、このC#のコードを眺めます。
private void button1_Click(object sender, EventArgs e)
{
var ar = GetEnum();
listBox1.Items.AddRange(ar.ToArray());
}
private IEnumerable<string> GetEnum()
{
yield return "Apple";
yield return "Banana";
yield return "Cat";
yield return "Dog";
}
GetEnumメソッドが実行されるのは、どのタイミングかというとlistBox1.Items.AddRangeの行なんですね。てっきりvar ar = GetEnum()の行かと思ってしまいますよね。ちょっとステップ実行してみてください。
まぁ遅延実行も別になくてもいいんですけど、LINQの演算子の標準実装がこれなんでちょっと気になりました。
クエリ式では定義済みの演算子を使用するだけなので別にVBでLINQの機能が制限されるとかそういうことではないです。ただ、メソッドベースのLINQを使うときに自作の拡張メソッドを作る場合にC#ならばyield returnを使用することで標準のLINQと同じような遅延評価ができるのに、VBだと自作の演算子だけ即時評価にならざるを得ないかなと思っただけです。
はい。別に自作演算子で即時評価が行われてもいまのところ特に困る気はしません。
| 固定リンク
「Visual Basic」カテゴリの記事
- LINQ独自拡張時の遅延実行(2008.05.26)
- C#のyieldを甘く見てました(2008.04.27)
- マイクロソフトが.NETのソースコードを公開する(2007.10.10)
- そろそろLINQ(2007.09.24)
- Enumの読み方(2007.09.21)


コメント
列挙する数が無限だったりする場合に便利ですね。
素数をどこまでも列挙し続けてforeachで回して、ループ内で適当にbreakして抜けたいような時に重宝してます。
投稿: あにす | 2008年4月30日 (水) 21時00分
なるほど。「列挙する数が無限」という発想はなかったです。
これも『コルーチン』なればこそですね。
うーん、VBにもyieldが欲しいです…
投稿: るきお | 2008年5月 1日 (木) 21時17分
面白いですね。勉強になりました。
アプリケーションのステータスによってコレクションの残りの要素が動的に変わるような時などに使えそうです。
投稿: seosoft | 2008年6月22日 (日) 17時18分