Tuesday, 13 June 2017

How to use C# Delegates?


Writing this mostly for when I need a quick snippet, but in case someone finds this useful.

The C# delegate beast is an object which holds references to methods (think “object-like method” that can be strong typed and therefore checked, unlike C++ function pointers), so this makes them super useful to pass as method parameters or to run a bunch of methods in event callbacks. This particular example uses Reactive Extensions so you will need to install them with Nuget.

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

using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Subjects;

namespace DelegateTest
{

    // Delegate definition. 
    public delegate void ProcessDelegate();

    public class Processor {

        // Reactive observable. 
        public Subject<Task> Observable = new Subject<Task>();

        // Task to process. 
        public void Process(Task Process) {
            Process.Start();
        }

        // Delegate instance. 
        public ProcessDelegate ProcessInstance;

        // Constructor. 
        public Processor(IEnumerable<ProcessDelegate> Processes, ProcessDelegate ProcessCompleted)
        {
            // Initialise delegate instance. 

            // Add process methods. 
            foreach (var Process in Processes)
                ProcessInstance += Process;
            
            // Add process completed method. 
            ProcessInstance += ProcessCompleted; 
        }       

    }







    public class Program
    {

        static void Main(string[] args)
        {

            Console.WriteLine("Starting process test ...");

            // Create test process object. 
            Processor Test = new Processor(

                // Delegate implementations. 
                new List<ProcessDelegate>
                {
                    () => {
                        string Result = "";
                        for(int Index = 0; Index < 100; Index++)
                            Result += Index.ToString();
                        Console.WriteLine("Process 1 finished = " + Result.Substring(0, 10) + " ... ");
                    },
                    () => {
                        string Result = "";
                        for(int Index = 0; Index < 100; Index++)
                            Result += Index.ToString();
                        Console.WriteLine("Process 2 finished = " + Result.Substring(0, 10) + " ... ");
                    },
                    () => {
                        string Result = "";
                        for(int Index = 0; Index < 100; Index++)
                            Result += Index.ToString();
                        Console.WriteLine("Process 3 finished = " + Result.Substring(0, 10) + " ... ");
                    }
                }, 

                () =>
                {
                    Console.WriteLine("Processes completed ... ");
                }

            );


            // Assign processes/delegate to an observable task. 
            Test.Observable.Subscribe(
                Value => Test.Process( Value ), 
                () =>
                {
                    Console.WriteLine("Observable OnCompleted called ... ");
                }
            );

            // Run action on the observable. 
            // Assigning delegate implementations. 
            Test.Observable.OnNext(
                new Task(new Action(Test.ProcessInstance))); 

            Console.WriteLine("Carrying on with some other tasks ..."); 
            

            Console.ReadLine(); 

        }

    }

}


Handy links:


No comments:

Post a Comment