
.NET 3.5+Func and Action Delegates (2)
The Func and Action generic delegates were introduced in the .NET framework version 3.5. They provide flexible delegates with generic parameters that can be used for many purposes, including passing lambda expressions to method parameters.
Action Delegate
As with Func, the Action delegate has five variations. These allow the encapsulation of methods that have up to four parameters but do not return a value. Again, all of the parameters are generic types allowing any type to be used for each argument. The five signatures are as follows:
public delegate void Action()
public delegate void Action<T, >(T arg)
public delegate void Action<T1, T2>(T1 arg1, T2 arg2)
public delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3)
public delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
Using Action
The simplest Action delegate is used with methods that accept no parameters and return no values. The following code demonstrates this with an anonymous method that outputs text to the console.
Action showMessage = delegate { Console.WriteLine("Hello, world"); };
showMessage(); // Outputs "Hello, world"
As with the Func delegates, Action can be used with lambda expressions. The equivalent of the previous example can be created using a statement lambda, as follows:
Action showMessage = () => { Console.WriteLine("Hello, world"); };
showMessage(); // Outputs "Hello, world"
Using Action with Parameters
As a final example of the basic use of Action, consider the following example. This code uses a single string parameter for the delegate. The parameter accepts a message to be outputted to the console.
Action<string> showMessage = delegate(string msg) { Console.WriteLine(msg); };
showMessage("Hello, world"); // Outputs "Hello, world"
This example can be recreated using a statement lambda that includes a parameter. In this case the string parameter's type is inferred.
Action<string> showMessage = (msg) => { Console.WriteLine(msg); };
showMessage("Hello, world"); // Outputs "Hello, world"
Using Generic Delegates as Parameter Types
The Func delegate is commonly used as the type for parameters of methods that accept lambda expressions. These include LINQ standard query operators and similar methods that you create in your own projects. We will demonstrate this with this article's final example.
The following method defines an array containing the names of ten fruits. The method returns a filtered list of these fruits based upon the delegate passed as the only argument. Note that the types assigned to the Func delegate specify that the encapsulated method must receive a single string parameter and return a Boolean value. We could execute the passed method against each fruit string in a for-each loop. However, for simplicity the example uses the "Where" query operator.
private static string[] Fruit(Func<string, bool> filter)
{
string[] fruit = new string[]
{ "Apple", "Banana", "Cherry", "Damson", "Elderberry", "Fig", "Grapefruit",
"Huckleberry", "Lemon", "Mango" };
return fruit.Where(filter).ToArray();
}
To test the method, add the following code to the Main method of a console application. This code calls the Fruit method, applying a filter that returns only fruit with a name shorter than six characters. The fruit names are then outputted.
string[] shortFruit = Fruit(f => f.Length < 6);
foreach (string fruit in shortFruit)
Console.WriteLine(fruit);
/* OUTPUT
Apple
Fig
Lemon
Mango
*/
4 April 2010