Uses of Action delegate in C#

C#LambdaDelegatesAction

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

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

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

You can use actions for short event handlers:

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

Solution 5 - C#

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.

Solution 6 - C#

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

Solution 7 - C#

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

Solution 8 - C#

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.

Solution 9 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBiswanathView Question on Stackoverflow
Solution 1 - C#Andrew HareView Answer on Stackoverflow
Solution 2 - C#Programmin ToolView Answer on Stackoverflow
Solution 3 - C#arulView Answer on Stackoverflow
Solution 4 - C#Aaron PowellView Answer on Stackoverflow
Solution 5 - C#Nathan WView Answer on Stackoverflow
Solution 6 - C#Binary WorrierView Answer on Stackoverflow
Solution 7 - C#Ron SkufcaView Answer on Stackoverflow
Solution 8 - C#SorskootView Answer on Stackoverflow
Solution 9 - C#eviloneView Answer on Stackoverflow