Array Collections File String Windows VB.NET Algorithm ASP.NET Cast Class Compression Convert Data Delegate Directive Enum Exception If Interface Keyword LINQ Loop Method .NET Number Regex Sort StringBuilder Struct Switch Time Value

Behavior too is an object. Delegates in the C# language are objects that reference a certain behavior. They are higher-order procedures. They can be passed as an argument to another procedure. They are similar to derived classes in that they are data objects that specify behavior.
Higher-order procedures can serve as powerful abstraction mechanisms, vastly increasing the expressive power of our language. Abelson & Sussman, p. 57
Let's review the syntax of the delegate type. You will need to declare the delegate type. The delegate type is declared with the delegate keyword. It describes the return values and parameters, with an empty block section. You can use this delegate declaration to create instances of the delegate type using the new operator.
Further, when you construct instances of the delegate type, the target method must have the exact same return value and arguments. When you look at this example, notice how the three Uppercase methods have the same return type and arguments as the UppercaseDelegate type.
Program that demonstrates delegate type [C#]
using System;
class Program
{
/// <summary>
/// Delegate declaration.
/// </summary>
delegate string UppercaseDelegate(string input);
/// <summary>
/// Delegate implementation 1.
/// </summary>
static string UppercaseFirst(string input)
{
char[] buffer = input.ToCharArray();
buffer[0] = char.ToUpper(buffer[0]);
return new string(buffer);
}
/// <summary>
/// Delegate implementation 2.
/// </summary>
static string UppercaseLast(string input)
{
char[] buffer = input.ToCharArray();
buffer[buffer.Length - 1] = char.ToUpper(buffer[buffer.Length - 1]);
return new string(buffer);
}
/// <summary>
/// Delegate implementation 3.
/// </summary>
static string UppercaseAll(string input)
{
return input.ToUpper();
}
/// <summary>
/// Receives delegate type.
/// </summary>
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));
}
}
Output
Your string before: perls
Your string after: Perls
Your string before: perls
Your string after: perlS
Your string before: perls
Your string after: PERLS
Description. So what happens inside the Main entry point in this program? The WriteOutput method is called three times, and it receives two arguments each time. The second argument is of type UppercaseDelegate. In Main, the UppercaseDelegate instances are constructed with the delegate constructor. The target method is specified as the sole argument.
Note: The target method is a method name, not a variable.
Calling delegate. In the WriteOutput method, then, an UppercaseDelegate instance is received as a parameter. To call the method specified by the delegate instance, you can simply use the two parentheses after the parameter name. This invokes the target method.
Anonymous functions in the C# language include lambda expressions. You can actually pass a lambda expression as the implementation of the delegate. For example, you can construct the UppercaseDelegate by specifying a lambda expression inside the constructor itself.
This is functionally equivalent to using a static method with the same return value and argument. You can see how delegate types enable higher-order procedures, where you can specify behaviors to methods as data.
Anonymous Function ExampleExample that uses lambda expression and delegate [C#]
using System;
class Program
{
// ...
// ... (Paste other methods here)
// ...
static void Main()
{
WriteOutput("perls", new UppercaseDelegate(x => x.ToUpper()));
}
}
Output
PERLSOverview: These C# examples use delegate methods. They show lambda expressions, anonymous methods, and types such as Predicate.
Next, this example program uses the Predicate generic delegate type with an int type parameter. It uses a lambda expression to specify that the function returns true when the argument is equal to 5. The Invoke method is then used to demonstrate that the Predicate works correctly.
Predicate TypeProgram that uses delegate [C#]
using System;
class Program
{
static void Main()
{
Predicate<int> predicate = value => value == 5;
Console.WriteLine(predicate.Invoke(4));
Console.WriteLine(predicate.Invoke(5));
}
}
Output
False
TrueThe syntax for delegate functions can be somewhat complicated. Lambda expressions provide a simplified and more terse way of specifying functions. They use the => syntax to separate formal parameters and the method body.
Lambda Expression
In the .NET Framework, Action instances represent a method that returns void. You can call Invoke on the Action instance and then the method will execute. These are very useful in a variety of program contexts.
Action Type Action Dictionary
Next, a Func instance is a delegate to a method that receives arguments and also returns a value. It can be used in the same general way as Action but with a return value.
Func TypeThe .NET Framework also provides a delegate type that is specifically used to compare objects. This is useful when calling the List.Sort or Array.Sort methods, as we demonstrate here.
Comparison Delegate
Events allow you to specify that when external event occurs, such as a mouse click, a delegate method should always be executed. Events are most commonly used in user interfaces such as Windows Forms.
Event Example
Although the delegate syntax can be confusing at first, once you understand the instantiation model and type system it is useful. Further, by enabling a straightforward syntax for higher-order procedures, the language offers the ability to specify actions as data. Once functions are collapsed into data objects, you can create richer object models and multi-purpose abstractions to solve your problems.