
Action objects return no values. The Action type in the C# language is similar to a void method. It must never return a value onto the evaluation stack when execution occurs. Action is found in the System namespace.
This page examines the C# Action type. It presents several examples of Action.

This program shows how you can use the Action type in C# programs to point to anonymous functions that never return a value onto the evaluation stack. An Action instance can receive parameters, but cannot return values. This means that an Action instance is similar to a void method. The program shows how you can Invoke the Action instances through the invocation mechanism provided by the type.
Program that uses Action type and Invoke [C#]
using System;
class Program
{
static void Main()
{
// Example Action instances.
// ... First example uses one parameter.
// ... Second example uses two parameters.
// ... Third example uses no parameter.
// ... None have results.
Action<int> example1 =
(int x) => Console.WriteLine("Write {0}", x);
Action<int, int> example2 =
(x, y) => Console.WriteLine("Write {0} and {1}", x, y);
Action example3 =
() => Console.WriteLine("Done");
// Call the anonymous methods.
example1.Invoke(1);
example2.Invoke(2, 3);
example3.Invoke();
}
}
Output
Write 1
Write 2 and 3
DoneOne parameter with Action. This program shows the Action type and its usage with three lambda expressions. The first Action instance uses the constructed type Action<int>, and an explicit parameter list in the lambda expression. It receives one argument when invoked, and returns no result.
Two parameters and no parameters. The second and third Action instances in this program also return no value. The Action type specifies a function that must never return a value through a return statement. The second Action receives two parameters, both of integer type. The third Action receives no parameters, and is a parameterless void method.
Invoke method on Action. The program also demonstrates the Invoke instance method on the Action type. The Invoke method receives a number of arguments equal to the specific type of Action. The Action type is a parameterized type, meaning it must have the types of the arguments specified at declaration. This information is determined at compile-time, before runtime.

How much slower are delegate method calls than direct method calls? To test this, we use the Action type with a single parameter. This program introduces the Method1 method, which contains some dummy code for testing.
Loops. In the first loop, Method1 is called directly one-hundred million times. In the second loop, an Action instance that points to Method1 is invoked the same number of times. The program shows how much slower Actions are than regular methods.
Program that tests Action invocation [C#]
using System;
using System.Diagnostics;
class Program
{
const int _max = 100000000;
static void Main()
{
// Create Action delegate for Method1.
Action<int> action = new Action<int>(Method1);
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
// Direct call.
Method1(5);
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
// Delegate call.
action.Invoke(5);
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
_max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
_max).ToString("0.00 ns"));
Console.Read();
}
static void Method1(int param)
{
// Dummy.
if (param == -1)
{
throw new Exception();
}
}
}
Output
0.32 ns
3.52 nsResults. According to the results here, for a method with one parameter and no return value, the Action invocation costs more than three nanoseconds extra each time. This is unlikely to cause many performance problems. Rather, it shows that the Action type is very efficient and should not be avoided.

Here we note the difference between the Action type as shown in this article and the Func type that you can also use. The Action type receives parameters but does not return a parameter.
The Func type, however, receives parameters and also returns a result value. The difference is that an Action never returns anything, while the Func always returns something. An Action is a void-style method in the C# language.
Func TypeActions can serve as an abstraction for various methods. In other words, an Action<int> can be an instance that points to any function that receives an int parameter.
However, you can design an abstract class with an abstract method that also can be used in this way. In the following program, we test such an abstract class against an Action<int>.
Abstract KeywordProgram that benchmarks abstract [C#]
using System;
using System.Diagnostics;
abstract class A
{
public abstract void MethodA(int y);
}
class AB : A
{
public override void MethodA(int y)
{
}
}
class Program
{
static void MethodA(int y)
{
}
static void Main()
{
A abst = new AB();
abst.MethodA(0);
Action<int> action = new Action<int>(MethodA);
action.Invoke(0);
const int max = 100000000;
var s1 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
abst.MethodA(i);
abst.MethodA(i);
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
action.Invoke(i);
action.Invoke(i);
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
max).ToString("0.00 ns"));
Console.Read();
}
}
Output
3.54 ns
6.68 nsResult. The result was that the Action was slower to call than the method from the abstract class reference. This means that if you can use class derivation and abstract classes instead of Actions, you will likely have a faster program.
Key point: Abstract method calls are faster than Action Invoke calls.
It is possible to use Action as the value in a Dictionary instance. This makes it possible to call functions by a string key. In this example, we invoke two static void methods based on simple string keys. The performance of this code sample is pretty good.
DictionaryProgram that uses Dictionary with Action [C#]
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Dictionary<string, Action> dict = new Dictionary<string, Action>();
dict["cat"] = new Action(Cat);
dict["dog"] = new Action(Dog);
dict["cat"].Invoke();
dict["dog"].Invoke();
}
static void Cat()
{
Console.WriteLine("CAT");
}
static void Dog()
{
Console.WriteLine("DOG");
}
}
Output
CAT
DOG
An alternative. One option here is to use a Dictionary of an abstract class. Then, you could instantiate each method as an instance of a derived class. You could use a method to override the virtual or abstract base method.
We looked at the Action type in the C# language. The Action type specifies a function object that can receive parameters, but never returns a value onto the evaluation stack. In other terms, Action instances are void methods. The Action instances can be called through the Invoke instance method, which receives the specific parameters.
Delegate Tutorial