This C# keyword (delegate) is used to create method objects. With the Invoke()
method, we can call a delegate as a method.
We can pass the delegate as an argument to another method. The function is an object—a delegate is a higher-order procedure.
This program declares a delegate type D that receives a string
, and returns no value. In Main
, we create an instance of type D.
using System; class Program { delegate void D(string value); static void Main() { // ... Specify delegate with lambda expression. D d = v => Console.WriteLine(v); // ... Invoke delegate. d.Invoke("cat"); } }cat
Next, we build upon the delegate concept. We declare a delegate type UppercaseDelegate
. It receives a string
, and returns a string
.
UppercaseDelegate
. When called, WriteOutput
invokes the function argument.using System; class Program { delegate string UppercaseDelegate(string input); static string UppercaseFirst(string input) { char[] buffer = input.ToCharArray(); buffer[0] = char.ToUpper(buffer[0]); return new string(buffer); } static string UppercaseLast(string input) { char[] buffer = input.ToCharArray(); buffer[buffer.Length - 1] = char.ToUpper(buffer[buffer.Length - 1]); return new string(buffer); } static string UppercaseAll(string input) { return input.ToUpper(); } static void WriteOutput(string input, UppercaseDelegate del) { Console.WriteLine("Your string before: {0}", input); Console.WriteLine("Your string after: {0}", del(input)); } static void Main() { // Wrap the methods inside delegate instances and pass to the method. WriteOutput("perls", new UppercaseDelegate(UppercaseFirst)); WriteOutput("perls", new UppercaseDelegate(UppercaseLast)); WriteOutput("perls", new UppercaseDelegate(UppercaseAll)); } }Your string before: perls Your string after: Perls Your string before: perls Your string after: perlS Your string before: perls Your string after: PERLS
We can use the delegate keyword inline to specify a function argument. Methods like FindAll
on List
can receive this kind of syntax.
static
method or lambda expression with the same return value and argument.using System; using System.Collections.Generic; class Program { static void Main() { List<int> values = new List<int>() { 1, 1, 1, 2, 3 }; // This syntax enables you to embed multiple statements in an anonymous function. List<int> res = values.FindAll(delegate(int element) { if (element > 10) { throw new ArgumentException("element"); } if (element == 8) { throw new ArgumentException("element"); } return element > 1; }); // Display results. foreach (int val in res) { Console.WriteLine(val); } } }2 3
The syntax for delegate functions can be complex. Lambda expressions provide a simple and terse way of specifying functions.
Predicate
, Action, Func
or Comparison
, a lambda can be passed.Events allow you to specify that when external event occurs, such as a mouse click, a delegate method should always be executed.
Delegate syntax is at first confusing. Once you understand the instantiation model and type system, it offers immense benefits to certain programs.
With the type system, the language offers the ability to specify actions as data. Complicated (and possibly hard-to-understand) programs can be written.