1
Write a post

Beginner's Guide to Delegates, Funcs and Actions in C#

Published Apr 22, 2016Last updated Apr 14, 2017
Beginner's Guide to Delegates, Funcs and Actions in C#

In this tutorial, I'll be giving a short introduction to delegates in C#.

So, what's a delegate?

In the same fashion that a class is a reference type that holds references to objects, delegates are also reference types, except they hold references to other methods.

To put it even more plainly, classes are to objects what delegates are to methods.

When you look at it from that perspective, they're actually not that different, both classes and delegates are declared in similar fashion and both of them are reference types.

The class reference type vs delegate reference type


Types of delegates

There's a number of different types of delegates that we will be covering:

  1. The Delegate type
  2. The Action type
  3. The Func type

The Delegate type

Declaration

The delegate type is declared by using the type name delegate, followed by the return type, name of the delegate and its input parameters.

// Structure of a delegate
delegate  <return.type>   <name>   (<type.parameter>)

// Example
delegate string Foo (int value);

To reference a method to a delegate, the signature of both the delegate and method must match completely so:

  • Return types must be the same.
  • Input parameters must also be the same (and in matching order).

Example

Below we're referencing the Bar method to the Foo delegate.

void Main()
{
    Foo fooExample = Bar;
    string time = fooExample(DateTime.UtcNow);
    Console.WriteLine (time);
}

public delegate string Foo (DateTime time);

public string Bar(DateTime value)
{
    return value.ToString("t");
}

Example 2 - Multicasting

Multiple delegate objects can be combined into a single instance, and it's the combination of delegates under that instance that becomes a Multicast delegate.

When the multicast delegates are invoked, they iterate through their list of delegates and invoke them in order.

Carrying on from the example above.

void Main()
{
    var now = DateTime.UtcNow;
    Foo fooTime, 
        fooDate, 
        fooMulticast;
        
    fooTime = BarTime;
    fooDate = BarDate;
    
    fooMulticast = fooTime + fooDate;
    
    
    Console.Write("FooTime: \n----\n");
    fooTime(now);
    Console.WriteLine ();
   
   /* - OUTPUT
        FooTime: 
        ----
        04:23
    */
    
    
    Console.Write("FooDate: \n----\n");
    fooDate(now);
    Console.WriteLine ();
   
   /* - OUTPUT
        FooDate: 
        ----
        21/04/2016
    */

    
    
    Console.Write("FooMulticast: \n----\n");
    fooMulticast(now);
  
   /* - OUTPUT
        FooMulticast: 
        ----
        04:23
        21/04/2016
    */
}

public delegate string Foo (DateTime time);

public string BarTime(DateTime value)
{   
    var str = value.ToString("t");
    Console.WriteLine ("{0}",str);
    
    return str;
}

public string BarDate(DateTime value)
{
    var str = value.ToString("dd/MM/yyyy");
    Console.WriteLine ("{0}",str);
    
    return str;
}

The Action delegate

The Action Delegate is a delegate which has a return type of void. The parameters of the action delegate are set using type parameters.

void Example()
{
    // Named method
    this.NamedActionDelegate = NamedMethod;
    this.NamedActionDelegate.Invoke("Hi", 5);
    // Output > Named said: Hi 5

    // Anonymous Function > Lambda
    this.AnonymousActionDelegate.Invoke("Foooo", 106);
    // Output > Anonymous said: Foooo 106
}

public Action<string, int> NamedActionDelegate { get; set; }
public Action<string, int> AnonymousActionDelegate = (text, digit) => Console.WriteLine ("Anonymous said: {0} {1}", text, digit);

public void NamedMethod(string text, int digit)
{
    Console.WriteLine ("Named said: {0} {1}", text, digit);
}

The Func delegate

The Func Delegate is similar to the Action Delegate, the difference being that Func can never return void, it will always require at least one type argument. As mentioned earlier, the type argument specified last dictates the return type of the delegate.

void Example()
{
    // Named method
    this.NamedFuncDelegate = NamedMethod;
    string namedResult = this.NamedFuncDelegate.Invoke(5);
    Console.WriteLine (namedResult);
    // Output > Named said: 5

    // Anonymous Function > Lambda
    string anonyResult = this.AnonymousFuncDelegate.Invoke(106);
    Console.WriteLine (anonyResult);
    // Output > Anonymous said: 106
}

public Func<int, string> NamedFuncDelegate { get; set; }
public Func<int, string> AnonymousFuncDelegate = (digit) => { return string.Format("Anonymous said: {0}", digit); };

public string NamedMethod(int digit)
{
    return string.Format ("Named said: {0}", digit);
}
Discover and read more posts from Aydin Adn
get started
Enjoy this post?

Leave a like and comment for Aydin

3
1
1Reply
(((Frederic Morin)))
a month ago

Really liked the simple explanation and easy examples

Get curated posts in your inbox

Learn programming by reading more posts like this