Pregunta

Yo estaba trabajando con los delegados de acción en C # con la esperanza de aprender más sobre ellos y pensando en los que podrían ser útiles.

¿Alguien ha utilizado el Delegado de Acción, y si es así ¿por qué? o ¿Podría dar algunos ejemplos en los que podría ser útil?

¿Fue útil?

Solución

MSDN dice:

  

Este delegado es utilizado por el   método y el Array.ForEach   List.ForEach método para realizar una   acción en cada elemento de la matriz o   lista.

Con excepción de eso, puede utilizarlo como un delegado genérico que tarda 1-3 parámetros sin devolver cualquier valor.

Otros consejos

Aquí hay un pequeño ejemplo que muestra la utilidad de la delegada de Acción

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);
    }
}

Observe que el método foreach itera la colección de nombres y ejecuta el método print contra cada miembro de la colección. Esta un poco de un cambio de paradigma para nosotros los desarrolladores de C # a medida que avanzamos hacia un estilo más funcional de la programación. (Para obtener más información sobre la ciencia de la computación detrás de él lee esto: http: // en. wikipedia.org/wiki/Map_(higher-order_function) .

Ahora bien, si usted está usando C # 3 Puede mancha de esto un poco con una expresión lambda, así:

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();
    }
}

Bueno, una cosa que podría hacer es si usted tiene un interruptor:

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

Y con el poder de la fuerza de acciones que puede a su vez que el interruptor en un diccionario:

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

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

...

methodList[SomeEnum](someUser);

O se podría aprovechar esta lejos:

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

....

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

A sólo un par de ejemplos. Por supuesto, el uso más obvio sería métodos de extensión LINQ.

Puede utilizar las acciones de los controladores de eventos cortos:

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

He utilizado el delegado acción como esta en un proyecto una vez:

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()}
    };

, que lo único que hace es almacenar una acción (llamada al método) contra un tipo de control de modo que puede borrar todos los controles de un formulario de nuevo a los valores predeterminados allí.

Para un ejemplo de cómo se usa Acción <>.

Console.WriteLine tiene una firma que satisifies 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);         
    }

Espero que esto ayude

Lo uso cuando estoy tratando con hilo cruzado ilegal Llamadas Por ejemplo:

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();
}));

Tengo que dar crédito a Reed Copsey SO usuario 65358 para la solución. Mi pregunta completa con respuestas es SO Pregunta 2587930

Lo utilicé como una devolución de llamada en un controlador de eventos. Cuando levanto el evento, paso en un método de tomar una cadena de un parámetro. Esto es lo que la recaudación del evento se ve así:

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

El Método:

   public void UpdateMethod(string SpecialCode){ }

La declaración de la clase es la de los eventos Args:

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

De esta manera puedo llamar al método que se pasa desde el controlador de eventos con un poco de parámetro para actualizar los datos. Lo utilizo para solicitar alguna información del usuario.

Utilizamos una gran cantidad de funcionalidad delegado de actuación en pruebas. Cuando necesitamos para construir un objeto predeterminado y posteriormente deberá modificarlo. Hice pequeño ejemplo. Para construir la persona objeto predeterminado (John Doe) utilizamos BuildPerson() función. Más tarde añadimos Jane Doe también, pero modificamos su fecha de nacimiento y el nombre y la altura.

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; }
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top