Delegates, Action Delegates, Func Delegates, and Lambda Expressions

Delegates

A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate. A Delegate can be thought of as a reference pointer to an object/method. When it gets called, it notifies all methods that reference the delegate.

Delegate Multicast Example (+=):

using UnityEngine;
using System.Collections;

public class MulticastScript : MonoBehaviour 
{
    delegate void MultiDelegate();
    MultiDelegate myMultiDelegate;
    

    void Start () 
    {
        myMultiDelegate += PowerUp;
        myMultiDelegate += TurnRed;
        
        if(myMultiDelegate != null)
        {
            myMultiDelegate();
        }
    }
    
    void PowerUp()
    {
        print ("Orb is powering up!");
    }
    
    void TurnRed()
    {
        renderer.material.color = Color.red;
    }
}

Action Delegates

You can use the Action(Of T) delegate to pass a method as a parameter without explicitly declaring a custom delegate. The benefit here is you don’t have to declare a delegate. The compiler is smart enough to figure out the proper types.

However there is a limitation, the corresponding method action must not return a value. (In C#, the method must return void.)

Action Delegate Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ModernLanguageConstructs
{
    class Program
    {
        static void Main(string[] args)
        {
            // Part 1 - First action that takes an int and converts it to hex
            Action<int> displayHex = delegate(int intValue)
            {
                Console.WriteLine(intValue.ToString("X"));
            };

            // Part 2 - Second action that takes a hex string and 
            // converts it to an int
            Action<string> displayInteger = delegate(string hexValue)
            {
                Console.WriteLine(int.Parse(hexValue,
                    System.Globalization.NumberStyles.HexNumber));
            };
            
            // Part 3 - exercise Action methods
            displayHex(16);
            displayInteger("10");
        }
    }
}

Func Delegates
This differs from Action<> in the sense that it supports parameters AND return values.
You can use this delegate to represent a method that can be passed as a parameter without explicitly declaring a custom delegate. The encapsulated method must correspond to the method signature that is defined by this delegate.
This means that the encapsulated method must have one parameter that is passed to it by value, and that it must return a value.
Func Delegate Example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ModernLanguageConstructs
{
    class Program
    {
        static void Main(string[] args)
        {
            // Part 1 - First Func&lt;&gt; that takes an int and returns a string
            Func&lt;int, string&gt; displayHex = delegate(int intValue)
            {
                return (intValue.ToString("X"));
            };

            // Part 2 - Second Func&lt;&gt; that takes a hex string and 
            // returns an int
            Func&lt;string, int&gt; displayInteger = delegate(string hexValue)
            {
                return (int.Parse(hexValue,
                    System.Globalization.NumberStyles.HexNumber));
            };

            // Part 3 - exercise Func&lt;&gt; delegates
            Console.WriteLine(displayHex(16));
            Console.WriteLine(displayInteger("10"));
        }
    }
}
 Lambda Expressions
A lambda expression is an anonymous function that can contain expressions and statements, and can be used to create delegates or expression tree types.
All lambda expressions use the lambda operator =>, which is read as “goes to”. The left side of the lambda operator specifies the input parameters (if any) and the right side holds the expression or statement block.
The lambda expression x => x * x is read “x goes to x times x.”
Lambda Expression Example:
private IEnumerator waitThenCallback(float time, Action callback)
{
   yield return new WaitForSeconds(time);
   callback();
}

void Start()
{
  splashScreen.show();

  StartCoroutine(waitThenCallback(5, () =&gt; 
         { Debug.Log("Five seconds have passed!"); }));
  StartCoroutine(waitThenCallback(10, () =&gt; 
         { Debug.Log("Ten seconds have passed!"); }));
  StartCoroutine(waitThenCallback(20, () =&gt; 
  {
    Debug.Log("Twenty seconds have passed!"); 
    splashScreen.hide();
  }));
}
Another Lambda Expression Example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ModernLanguageConstructs
{
    class Program
    {
        static void Main(string[] args)
        {
            // Part 1 - An action and a lambda
            Action&lt;int&gt; displayHex = intValue =&gt;
            {
                Console.WriteLine(intValue.ToString("X"));
            };

            Action&lt;string&gt; displayInteger = hexValue =&gt;
            {
                Console.WriteLine(int.Parse(hexValue,
                    System.Globalization.NumberStyles.HexNumber));
            };

            // Part 2 - Use the lambda expressions
            displayHex(16);
            displayInteger("10");

        }
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *