Uses of Action delegate in C# [closed]

2020-01-25 12:02发布

问题:

Closed. This question needs to be more focused. It is not currently accepting answers.

Want to improve this question? Update the question so it focuses on one problem only by editing this post.

Closed 2 years ago.

I was working with the Action Delegates in C# in the hope of learning more about them and thinking where they might be useful.

Has anybody used the Action Delegate, and if so why? or could you give some examples where it might be useful?

回答1:

MSDN says:

This delegate is used by the Array.ForEach method and the List.ForEach method to perform an action on each element of the array or list.

Except that, you can use it as a generic delegate that takes 1-3 parameters without returning any value.



回答2:

Here is a small example that shows the usefulness of the Action delegate

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

Notice that the foreach method iterates the collection of names and executes the print method against each member of the collection. This a bit of a paradigm shift for us C# developers as we move towards a more functional style of programming. (For more info on the computer science behind it read this: http://en.wikipedia.org/wiki/Map_(higher-order_function).

Now if you are using C# 3 you can slick this up a bit with a lambda expression like so:

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


回答3:

Well one thing you could do is if you have a switch:

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

And with the might power of actions you can turn that switch into a dictionary:

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

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

...

methodList[SomeEnum](someUser);

Or you could take this farther:

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

....

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

Just a couple of examples. Of course the more obvious use would be Linq extension methods.



回答4:

You can use actions for short event handlers:

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


回答5:

I used the action delegate like this in a project once:

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

which all it does is store a action(method call) against a type of control so that you can clear all the controls on a form back to there defaults.



回答6:

For an example of how Action<> is used.

Console.WriteLine has a signature that 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);         
    }

Hope this helps



回答7:

I use it when I am dealing with Illegal Cross Thread Calls For example:

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

I must give credit to Reed Copsey SO user 65358 for the solution. My full question with answers is SO Question 2587930



回答8:

I used it as a callback in an event handler. When I raise the event, I pass in a method taking a string a parameter. This is what the raising of the event looks like:

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

The Method:

   public void UpdateMethod(string SpecialCode){ }

The is the class declaration of the event Args:

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

This way I can call the method passed from the event handler with a some parameter to update the data. I use this to request some information from the user.



回答9:

We use a lot of Action delegate functionality in tests. When we need to build some default object and later need to modify it. I made little example. To build default person (John Doe) object we use BuildPerson() function. Later we add Jane Doe too, but we modify her birthdate and name and height.

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