33 votes

délégués anonymes en C #

Je ne peux pas être le seul à être fatigués de définir et de nommer un délégué pour juste un seul appel à quelque chose qui nécessite un délégué. Par exemple, je voulais appeler .Refresh (), dans une forme peut-être d'autres threads, donc j'ai écrit ce code:

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

Je ne suis même pas sûr que je le dois, je viens de lire assez d'avoir peur que cela ne fonctionne pas à un stade ultérieur.
InvokeDelegate est effectivement déclaré dans un autre fichier, mais ai-je vraiment besoin d'un ensemble de délégué dédié juste pour cela? n'existe-il pas un médicament générique, les délégués à tous?
Je veux dire, par exemple, il y a un Stylo de classe, mais il y a aussi des Stylos.stylo de choix afin de ne pas avoir à refaire l'ensemble de la chose. Ce n'est pas la même, mais j'espère que vous comprenez ce que je veux dire.

52voto

skb Points 5933

Oui. Dans .NET 3.5, vous pouvez utiliser les délégués Func et Action . Les délégués Func renvoient une valeur, tandis que les délégués Action renvoient void. Voici à quoi ressemblent les noms de types:

 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)
 

Je ne sais pas pourquoi ils se sont arrêtés à 4 arguments chacun, mais cela a toujours été suffisant pour moi.

26voto

BrightUmbra Points 13844

Il y a le délégué Action que vous pouvez utiliser, comme ceci:

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

Ou, avec la syntaxe lambda:

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

Enfin, il existe une syntaxe de délégué anonyme:

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

8voto

Brian ONeil Points 3012

Dans ce cas spécifique, vous pouvez (et devriez) simplement utiliser MethodInvoker pour faire cela ... c'est pourquoi il existe.

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

Si vous faites quelque chose d'autre, vous pouvez, comme d'autres l'ont déjà fait, utiliser Func <T, ...> ou Action <T, ...> si cela vous convient.

4voto

Fredrik Mörk Points 85694

Version courte:

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

Ensuite, vous pouvez également laisser tomber la vérification de InvokeRequired; vous pouvez simplement l'appeler tel quel. Fonctionne également si vous devez passer des paramètres, vous n'avez donc pas besoin d'autres délégués spécifiques aux paramètres (fonctionne aussi bien avec le délégué Action sans paramètre):

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

2voto

Juliet Points 40758

Ai-je vraiment besoin d'un ensemble de délégué dédié juste pour cela? il n'existe pas de un médicament générique, les délégués à tous?

Définition de vos propres délégués peuvent vraiment faire un débogage plus facile, si seulement parce que Intellisense peut vous dire les noms de vos paramètres. Par exemple, vous écrivez un délégué comme ceci:

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

Lorsque vous utilisez ce code .NET vous informe des noms de paramètre, nom du délégué, etc, donc il y a beaucoup de contexte de droit délégué de définition si vous ne savez pas exactement comment quelque chose est utilisé.

Toutefois, si vous ne me dérange pas de sacrifier Intellisense, il y a déjà une classe de délégués definined dans l'espace de noms du Système qui peut être utilisé comme ad-hoc des délégués:

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>

Seulement Action et Action exister .NET 2.0, mais son assez facile de déclarer une classe d'assistance avec les autres délégués dont vous avez besoin pour ce genre de diverses fonctions ad hoc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X