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); | |
} | |
} |
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(); |
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
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(); | |
} | |
} |
I'm Chris Small, a software engineer working in London. This is my tech blog. Find out more about me via Github, Stackoverflow, Resume