C# でイベントハンドラを yield return してみよう
以前、yield return に関してこんな記事を書いた。
C# の yield return の使い道 - カタチづくり
簡単に説明すると、直線作図の機能を下記のような状態遷移モデルで捉えて、これを IEnumerator を利用して実装しようと言う話。
この記事を受けて、実際に実装してくれた人がいた。ありがとうございます。
yield(いーるど)は、つまるところコルーチンなんだよね - Bug Catharsis
僕が書いたアイデアが簡潔に実装できていると思う。ただ、イベントハンドラを yield return してしまうほうがよりクールだと思うのでご紹介。
using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; class MyForm : Form { static void Main() { Application.Run( new MyForm() ); } readonly List<Action<Graphics>> _entities = new List<Action<Graphics>>(); IEnumerator<MouseEventHandler> _handler; public MyForm() { this.Paint += ( sender, e ) => { foreach ( var draw in _entities ) draw( e.Graphics ); }; this.MouseClick += ( sender, e ) => { if ( _handler != null ) { _handler.Current( this, e ); this.MoveNext(); } }; _handler = this.DrawLines(); this.MoveNext(); } void MoveNext() { if ( !_handler.MoveNext() ) { _handler.Dispose(); _handler = null; } } IEnumerator<MouseEventHandler> DrawLines() { while ( true ) { var p1 = new Point(); var p2 = new Point(); yield return ( sender, e ) => p1 = e.Location; yield return ( sender, e ) => p2 = e.Location; _entities.Add( g => g.DrawLine( new Pen( Brushes.Black ), p1, p2 ) ); this.Invalidate(); } } }
DrawLines() 関数で MouseEventHandler を yield return しているところにご注目。何かの参考になれば幸いです。