Windows フォームなんかの古いライブラリで引数が Delegate のメソッドにラムダ式を書いたりすると「ラムダ式 はデリゲート型ではないため、'Delegate' 型に変換できません。」と怒られます。
// こんな風に書くと怒られる public partial class FormMain : Form { private async void button_Click(object sender, EventArgs e) { awaita Task.Run(() => { this.Invoke(() => _time.Start()); // CS1660 ラムダ式 はデリゲート型ではないため、'Delegate' 型に変換できません。 }); } } // ★Invokeはメソッドの引数がDelegateになってる public object Invoke(Delegate method);
こういう場合、以下のようにすればエラーが解消します。
// NG // this.Invoke(() => _time.Start()); // こうすると通るようになる this.Invoke(new Action(() => _time.Start()));
Delegate → Actionデリゲート → ラムダ式、のように間接的に関係を作ると引数にすることができます。
余談ですが、イベントが呼び出されるたびに new でインスタンスが作成されるのを避けたい場合以下のように記述します。
// 毎回newするのを避ける public partial class FormMain : Form { // (1)ラムダ式を保存するフィールド readonly Action _action; public FormMain() { InitializeComponent(); // (2)コンストラクター内でラムダ式を設定 _action = new Action(() => _time.Start()); } private async void button_Click(object sender, EventArgs e) { awaita Task.Run(() => { // (3)ここで使用する this.Invoke(_action); }); } }
久しぶりに書いたら忘れてたのでメモ。