web-dev-qa-db-fra.com

Délégué Uses of Action en C #

Je travaillais avec les délégués d’action en C # dans l’espoir d’en apprendre davantage sur eux et de réfléchir aux domaines où ils pourraient être utiles.

Quelqu'un a-t-il utilisé le délégué à l'action et, dans l'affirmative, pourquoi? ou pourriez-vous donner quelques exemples où cela pourrait être utile?

132
Biswanath

MSDN dit:

Ce délégué est utilisé par la méthode Array.ForEach et la méthode List.ForEach pour effectuer une action sur chaque élément du tableau ou de la liste.

Sauf que, vous pouvez l'utiliser comme délégué générique prenant 1 à 3 paramètres sans renvoyer de valeur.

25
arul

Voici un petit exemple qui montre l'utilité du délégué Action

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        Action<String> print = new Action<String>(Program.Print);

        List<String> names = new List<String> { "andrew", "nicole" };

        names.ForEach(print);

        Console.Read();
    }

    static void Print(String s)
    {
        Console.WriteLine(s);
    }
}

Notez que la méthode foreach itère la collection de noms et exécute la méthode print sur chaque membre de la collection. Cela change un peu le paradigme pour nous, les développeurs C #, alors que nous nous dirigeons vers un style de programmation plus fonctionnel. (Pour plus d'informations sur l'informatique, lisez ceci: http://en.wikipedia.org/wiki/Map_ (higher-order_function) .

Maintenant, si vous utilisez le C # 3, vous pouvez lisser un peu cela avec une expression lambda comme ceci:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<String> names = new List<String> { "andrew", "nicole" };

        names.ForEach(s => Console.WriteLine(s));

        Console.Read();
    }
}
114
Andrew Hare

Eh bien, une chose que vous pourriez faire est si vous avez un commutateur:

switch(SomeEnum)
{
  case SomeEnum.One:
      DoThings(someUser);
      break;
  case SomeEnum.Two:
      DoSomethingElse(someUser);
      break;
}

Et avec la puissance des actions, vous pouvez transformer ce commutateur en dictionnaire:

Dictionary<SomeEnum, Action<User>> methodList = 
    new Dictionary<SomeEnum, Action<User>>()

methodList.Add(SomeEnum.One, DoSomething);
methodList.Add(SomeEnum.Two, DoSomethingElse); 

...

methodList[SomeEnum](someUser);

Ou vous pourriez prendre ceci plus loin:

SomeOtherMethod(Action<User> someMethodToUse, User someUser)
{
    someMethodToUse(someUser);
}  

....

var neededMethod = methodList[SomeEnum];
SomeOtherMethod(neededMethod, someUser);

Juste quelques exemples. Bien entendu, l’utilisation la plus évidente serait les méthodes d’extension Linq.

67
Programmin Tool

Vous pouvez utiliser des actions pour des gestionnaires d'événements courts:

btnSubmit.Click += (sender, e) => MessageBox.Show("You clicked save!");
16
Aaron Powell

J'ai utilisé le délégué d'action comme celui-ci dans un projet une fois:

private static Dictionary<Type, Action<Control>> controldefaults = new Dictionary<Type, Action<Control>>() { 
            {typeof(TextBox), c => ((TextBox)c).Clear()},
            {typeof(CheckBox), c => ((CheckBox)c).Checked = false},
            {typeof(ListBox), c => ((ListBox)c).Items.Clear()},
            {typeof(RadioButton), c => ((RadioButton)c).Checked = false},
            {typeof(GroupBox), c => ((GroupBox)c).Controls.ClearControls()},
            {typeof(Panel), c => ((Panel)c).Controls.ClearControls()}
    };

il ne fait que stocker une action (appel de méthode) contre un type de contrôle afin que vous puissiez effacer tous les contrôles d’un formulaire avec leurs valeurs par défaut.

14
Nathan W

Pour un exemple d'utilisation de l'action <>.

Console.WriteLine a une signature qui satisfait à Action<string>.

    static void Main(string[] args)
    {
        string[] words = "This is as easy as it looks".Split(' ');

        // Passing WriteLine as the action
        Array.ForEach(words, Console.WriteLine);         
    }

J'espère que cela t'aides

13
Binary Worrier

Je l'utilise quand j'ai affaire à des appels croisés illégaux. Par exemple:

DataRow dr = GetRow();
this.Invoke(new Action(() => {
   txtFname.Text = dr["Fname"].ToString();
   txtLname.Text = dr["Lname"].ToString(); 
   txtMI.Text = dr["MI"].ToString();
   txtSSN.Text = dr["SSN"].ToString();
   txtSSN.ButtonsRight["OpenDialog"].Visible = true;
   txtSSN.ButtonsRight["ListSSN"].Visible = true;
   txtSSN.Focus();
}));

Je dois donner crédit à Reed Copsey SO utilisateur 65358 pour la solution. Ma question complète avec réponses est SO Question 25879

11
Ron Skufca

Je l'ai utilisé comme un rappel dans un gestionnaire d'événements. Lorsque je déclenche l'événement, je passe une méthode en prenant une chaîne un paramètre. Voici à quoi ressemble l'évènement de l'événement:

SpecialRequest(this,
    new BalieEventArgs 
    { 
            Message = "A Message", 
            Action = UpdateMethod, 
            Data = someDataObject 
    });

La méthode:

   public void UpdateMethod(string SpecialCode){ }

La est la déclaration de classe de l'événement Args:

public class MyEventArgs : EventArgs
    {
        public string Message;
        public object Data;
        public Action<String> Action;
    }

De cette façon, je peux appeler la méthode transmise par le gestionnaire d'événements avec un paramètre quelconque pour mettre à jour les données. J'utilise ceci pour demander des informations à l'utilisateur.

3
Sorskoot

Nous utilisons beaucoup de fonctionnalités de délégué Action dans les tests. Lorsque nous avons besoin de construire un objet par défaut et de le modifier ultérieurement. J'ai fait petit exemple. Pour construire l'objet personne par défaut (John Doe), nous utilisons la fonction BuildPerson(). Plus tard, nous ajoutons également Jane Doe, mais nous modifions sa date de naissance, son nom et sa taille.

public class Program
{
        public static void Main(string[] args)
        {
            var person1 = BuildPerson();

            Console.WriteLine(person1.Firstname);
            Console.WriteLine(person1.Lastname);
            Console.WriteLine(person1.BirthDate);
            Console.WriteLine(person1.Height);

            var person2 = BuildPerson(p =>
            {
                p.Firstname = "Jane";
                p.BirthDate = DateTime.Today;
                p.Height = 1.76;
            });

            Console.WriteLine(person2.Firstname);
            Console.WriteLine(person2.Lastname);
            Console.WriteLine(person2.BirthDate);
            Console.WriteLine(person2.Height);

            Console.Read();
        }

        public static Person BuildPerson(Action<Person> overrideAction = null)
        {
            var person = new Person()
            {
                Firstname = "John",
                Lastname = "Doe",
                BirthDate = new DateTime(2012, 2, 2)
            };

            if (overrideAction != null)
                overrideAction(person);

            return person;
        }
    }

    public class Person
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public DateTime BirthDate { get; set; }
        public double Height { get; set; }
    }
2
evilone