2009-06-10 17 views
33

デリゲートを必要とするものへの単なる呼び出しのために、デリゲートの定義と命名に疲れている唯一の人になることはできません。例えば、私はおそらく他のスレッドからフォームで.Refresh()を呼び出してみたかったので、私はこのコードを書いた:私は、私はちょうど十分に読まなければならないことを怖がっすることさえわからないC#の匿名デリゲート

private void RefreshForm() 
{ 
    if (InvokeRequired) 
     Invoke(new InvokeDelegate(Refresh)); 
    else 
     Refresh(); 
} 

を後の段階では機能しません。
InvokeDelegateは、実際には別のファイルで宣言されていますが、私は本当には、このためだけの専用全体デリゲートを必要のですか?一般的な代議員はまったくありませんか?
たとえば、ペンクラスがありますが、ペンもあります。 pen-of-choiceあなたは全体をリメイクする必要はありません。それは同じではありませんが、あなたが私が何を意味するのか理解していただければ幸いです。

+1

C#には「匿名の代理人」はありません。デリゲート(使用しているもののようなもの)と匿名メソッド(デリゲートを介してのみアクセス可能)があります。 – Lucas

+3

私はC#の仕様が正しい方法であるということを "匿名メソッド"という用語を使用していると思います。しかし、この用語は、多くの人が匿名メソッドをパラメータとしてインスタンス化したデリゲートを意味するために使用されます。したがって、同じことを意味しますが、誰かが1つの用語を他の用語よりも使用する可能性があるコンテキストは、代理割り当てが行われているかどうか、または匿名メソッドが別のメソッドに直接渡されているかどうかによって異なります。私は反対の議論を歓迎する。 –

答えて

52

はい。 .NET 3.5ではFuncActionの代理人を使用できます。 Funcデリゲートは値を返し、Actionデリゲートはvoidを返します。

System.Func<TReturn> // (no arg, with return value) 
System.Func<T, TReturn> // (1 arg, with return value) 
System.Func<T1, T2, TReturn> // (2 arg, with return value) 
System.Func<T1, T2, T3, TReturn> // (3 arg, with return value) 
System.Func<T1, T2, T3, T4, TReturn> // (4 arg, with return value) 

System.Action // (no arg, no return value) 
System.Action<T> // (1 arg, no return value) 
System.Action<T1, T2> // (2 arg, no return value) 
System.Action<T1, T2, T3> // (3 arg, no return value) 
System.Action<T1, T2, T3, T4> // (4 arg, no return value) 

彼らは4つの引数ごとに停止した理由を私は知らないが、それは常に私のために十分なされています:ここでは型の名前がどのように見えるかです。

+2

4は具体的なルールではありませんが、これを過ぎると、少なくとも何らかの方法でパラメータを組み合わせることを検討する必要があります。 –

+1

古い.NETコードを3.5に移植すると、代理人が表示されますが、FuncまたはActionのいずれかに置き換えます。 – RichardOD

+10

フレームワークの次のバージョンには、4つ以上のパラメータのFuncとActionが含まれます。 –

4

ショートバージョン:

Invoke((MethodInvoker)delegate { Refresh(); }); 

その後、あなたはまた、InvokeRequiredのチェックをドロップすることができます。あなたはそれをそのまま呼び出すことができます。

private void SetControlText(Control ctl, string text) 
{ 
    Invoke((MethodInvoker)delegate { ctl.Text = text; }); 
} 
+0

匿名デリゲートを作成して既存のデリゲートタイプにキャストするのはなぜですか?デリゲートタイプは直接使用してください。 –

+2

@Brian:次のような意味です:Invoke(new MethodInvoker(delegate {ctl.Text = text;})); ?私が見ることができる限り、上記のコードと同じILコードが生成されるので、個人的な味わいにはなりません。 –

+0

MethodInvokerとActionの違いは何ですか? また、私はInvokeRequiredをチェックしています。これは、より速いなどの方が良いと思われるためです。 – Nefzen

26

あなたが使用できるアクションデリゲートがあります:あなたはパラメータを渡す必要があるので、他のパラメータの特定の代表団は必要(だけでなく、パラメータなしのアクションデリゲートと同じようにうまく動作しますが)存在しない場合にも動作します、そのような:

private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke(new Action(Refresh)); 
    else Refresh(); 
} 

あるいは、ラムダ構文を持つ:

private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke((Action)(() => Refresh())); 
    else Refresh(); 
} 

最後に、匿名デリゲートの構文があります:

private void RefreshForm() 
{ 
    if (InvokeRequired) Invoke((Action)(delegate { Refresh(); })); 
    else Refresh(); 
} 
+2

奇妙なことに、2番目と3番目の構文は、デリゲート型ではないため、System.Delegateに変換できないと言って動作しません。しかし、アクションは私が欲しいものです。 – Nefzen

+1

匿名デリゲートは、型デリゲートではないため、この方法でInvokeに渡すことはできません。あなたがここに書いたものはコンパイルされません。 –

+1

Heh、それは私が投稿する前にチェックしていないために得るものです。私はできるだけ早く修正します。 –

1

はい、汎用代理人があります。 Action<T1, T2...>は、いくつかのパラメータを取り、値を返さない汎用的な代理人です。Func<T1, T2...R>は、いくつかのパラメータを取り、値を返す汎用の代理人です。

2

私は本当に全員がこのために専用の代理人 を必要としていますか?そこにはありません 総称代議員はまったくですか?

Intellisenseがパラメータの名前を教えることができるため、独自の代理人を定義すると、実際にデバッグが容易になります。たとえば、次のようなデリゲートを書く:あなたはそれをコードを使用すると

public delegate int UpdateDelegate(int userID, string city, string, state, string zip); 

、.NETは、パラメータ名を知らせる名前を委任するなど、その場合は、コンテキストの多くは、右のデリゲートの定義にありますでしょう正確に何かが使われているかどうかはわかりません。

Func<T> 
Func<T, U> 
Func<T, U, V> 
Func<T, U, V, W> 
Action, Action<T> 
Action<T, U> 
Action<T, U, V> 
Action<T, U, V, W> 

のみActionActionが中に存在する:あなたはインテリセンスを犠牲にする気にしない場合

しかし、アドホック代表団として使用することができ、System名前空間にdefinined代表団のクラスがすでにあります.NET 2.0ですが、これらの種類の雑多なアドホック関数に必要な残りの代理人と共にヘルパークラスを宣言するのは簡単です。

8

この特定のケースでは、これを行うにはMethodInvokerを使用することができます(これは必須です)。

if (InvokeRequired) 
    Invoke(new MethodInvoker(Refresh)); 
else 
    Refresh(); 

あなたが何かをやっていた場合は、あなたは、他の人が答えてきたように、使用のFunc < T、... >またはアクション< Tは、... >は、彼らはあなたのユースケースに合うことができれば。

+1

これは.NET 2.0に最適なソリューションです –