Delegate型の引数にラムダ式を使う方法

C#

この記事は、一言でいうと、
「Disparcher.BeginInvokeに
ラムダ式書けないのなんとかならんの?!」

に対する回答です。
結論から言うと、

さんさめ
さんさめ

Actionに明示的にキャストすれば呼べる!

ということになります。
詳細は以下をご覧ください。

スポンサーリンク

Dispatcher.BeginInvokeにはラムダ式を渡せない

WPFで開発していると必ず悩まされるのが、
UIスレッドで作ったコントロールに
別スレッドからアクセスして例外になるパターンです。

UIスレッド以外からビュー要素にアクセスすると例外になる

そこで活用されるのが、
Dispatcher.Invoke
Dispatcher.BeginInvokeを用いて、
UIスレッドからアクセスさせる方法です。

これなら大丈夫

ところが、
Dispatcher.BeginInvokeの方は、
引数にActionを取るオーバーライドが存在しません。

よって、ラムダ式を渡そうとすると、
以下のようにコンパイルエラーになります。

Delegate型として正式に渡すためには、
わざわざ宣言をしないといけません。
次のように無駄な記述が増えてしまいます。

こんなこと書きたくないですよね。
あることをすれば普通にラムダ式を渡せます

明示的にActionにキャストすればラムダ式を渡せる

その方法とは、
「ラムダ式自体をActionに明示的にキャストする」
これだけです。

以下のように書きましょう。

これで問題なくきちんと動作します。
ちょっと括弧の数は多いですが、
delegate宣言するよりは圧倒的に記述が減りました。

どうやら、
ラムダ式は直接Delegate型に変換できないのですが、
Action型は引数、戻り値がはっきりしているため、
暗黙にDelegate型に変換できるみたいです。
そして引数、戻り値なしのラムダ式はActionにキャストできます。

さんさめ
さんさめ

じゃあラムダ式も直接
Delegate型に変換
してよ!

ラムダ式の引数、戻り値までは推定できない、
ってことなのかもしれませんね…。
いや、他の文脈ではできてますよね…?

まとめ

まとめです。

  • Dispatcher.BeginInvokeにはラムダ式を直接渡せない
  • Delegate型のインスタンスを作るのは面倒
  • ラムダ式をActionに明示的にキャストすれば渡せるようになる

最後までお読みいただきありがとうございました。

コメント

タイトルとURLをコピーしました