Chris's coding blog

Delegates, Funcs and Actions by example

May 03, 2010

This is a small set of reference examples of the various ways of declaring delegates, funcs and actions across the different versions of the framework and C#. I haven’t included any examples of passing Funcs,Actions as method parameters and interogating them, but Jon Skeet has a good post on it, and this stackoverflow question also demonstrates Action based operations quite succinctly. None of this article is under-the-hood in depth stuff - just a simple reference.

I haven’t included Expressions and System.Linq.Expression - there’s a large MSDN article on Expression trees which is very detailed already. A great example usage of Expressions is found in Fluent NHibernate and the source for its ClassMap class.

Delegates

The Delegate class is the base class for delegate types. However, only the system and compilers can derive explicitly from the Delegate class

public class DelegateExample
{
private delegate bool myDelegate(string s);
private bool IsBob(string name)
{
return name == "bob";
}
public void Run()
{
//
// This is just to show the Func's equivalent delegate way of doing things, which is less code here,
// but you end up repeating delegates everywhere.
//
// Syntax:
// - method1. is C# 3.0
// - method2. is C# 2.0
// - method3. is C# 1.0
// - method4. is C# 2.0+
//
myDelegate method1 = ((name) => name == "bob");
myDelegate method2 = delegate(string name)
{
return name == "bob";
};
myDelegate method3 = new myDelegate(IsBob);
myDelegate method4 = IsBob; // Shorthand for the above
bool isBob1 = method1("bob");
bool isBob2 = method2("bob");
bool isBob3 = method3("bob");
bool isBob4 = method4("bob");
Console.WriteLine(isBob1);
Console.WriteLine(isBob2);
Console.WriteLine(isBob3);
Console.WriteLine(isBob4);
}
}
view raw gistfile1.cs hosted with ❤ by GitHub

Func<TResult,..>

Func Encapsulates a method that has one parameter and returns a value of the type specified by the TResult parameter.

The biggest difference with Func and Action (introduced in .NET 3.5) and delegates, aside from removing delegate definition repetition, is you can declare your Func inside a method and aren’t restricted to declaring at a field level. From what I can tell and I maybe wrong, this restriction on non-field delegate definitions is to avoid confusion with the anonymous method (funcMethod2) way of doing inline delegates.

Func<string, bool> funcMethod1 = name => name == "bob"; // non-bracketed version of method1
Func<string, bool> funcMethod2 = delegate(string name)
{
return name == "bob";
};
Func<string, bool> funcMethod3 = new Func<string, bool>(IsBob);
Func<string, bool> funcMethod4 = IsBob; // Shorthand for the above
bool isFuncBob1 = method1("bob");
bool isFuncBob2 = method2("bob");
bool isFuncBob3 = method3("bob");
Console.WriteLine(isFuncBob1);
Console.WriteLine(isFuncBob2);
Console.WriteLine(isFuncBob3);
Console.ReadLine();
view raw gistfile1.cs hosted with ❤ by GitHub

Action<T,..>

Action encapsulates a method that takes a single parameter and does not return a value.

Action was introduced in .NET 2.0 alongside helpers such as EventHandler that made a lot of repetitive delegate definitions redundant.

public class ActionExample
{
private List<string> _names = new List<string>();
private delegate void myDelegate(string s);
private void AddName(string name)
{
_names.Add(name);
}
public void Run()
{
// The delegate equivalent just uses void instead of string.
Action<string> actionMethod1 = name => _names.Add(name);
Action<string> actionMethod2 = delegate(string name)
{
_names.Add(name);
};
Action<string> actionMethod3 = AddName;
actionMethod1("bob");
actionMethod2("jon");
actionMethod3("fred");
_names.ForEach(name => Console.WriteLine(name));
Console.ReadLine();
}
}
view raw gistfile1.cs hosted with ❤ by GitHub

csharp

I'm Chris Small, a software engineer working in London. This is my tech blog. Find out more about me via GithubStackoverflowResume