1. ホーム
  2. c#

[解決済み] Invokeコールの匿名メソッド

2022-06-14 11:08:24

質問

Control.Invokeの中で匿名でデリゲートを呼び出す構文に少し困っています。

私たちはさまざまなアプローチを試みましたが、すべて無駄でした。

たとえば

myControl.Invoke(delegate() { MyMethod(this, new MyEventArgs(someParameter)); }); 

ここで、someParameter はこのメソッドにローカルなものです。

上記はコンパイラエラーになります。

無名メソッドはデリゲート型ではないため、'System.Delegate'型に変換できません。

どのように解決するのですか?

なぜなら Invoke / BeginInvoke 受け入れる Delegate (型付きデリゲートではなく)どのようなタイプのデリゲートを作成するかコンパイラに指示する必要があります。 MethodInvoker (2.0)または Action (3.5)が一般的な選択です(同じシグネチャであることに注意)。

control.Invoke((MethodInvoker) delegate {this.Text = "Hi";});

パラメータを渡す必要がある場合は、"キャプチャー変数"が方法です。

string message = "Hi";
control.Invoke((MethodInvoker) delegate {this.Text = message;});

(注意: キャプチャの 非同期 が、しかし 同期 は大丈夫です - つまり、上記は大丈夫です)

もう一つの方法は、拡張メソッドを書くことです。

public static void Invoke(this Control control, Action action)
{
    control.Invoke((Delegate)action);
}

にしてから

this.Invoke(delegate { this.Text = "hi"; });
// or since we are using C# 3.0
this.Invoke(() => { this.Text = "hi"; });

もちろん、同じように BeginInvoke :

public static void BeginInvoke(this Control control, Action action)
{
    control.BeginInvoke((Delegate)action);
}

C# 3.0が使えない場合は、通常のインスタンスメソッドで同じことをすることができます。 Form ベースクラスで行うことができます。