Thursday, September 10, 2020

Delegates

  • Delegate is an object that knows how to call a method or a  group of methods which have the same signature. 
  • It is a reference to a function.
  • Of course, we can call methods directly, but we need delegates for designing extensible and flexible applications. (Ex: Frameworks).
  • Imagine that you are designing a framework which is use for processing the photos. In that framework, you have defined few photo processing ways such as "Apply Brightness" , "Apply Contrast" and etc. In future, may be a client who is using your framework need to add their own photo filter which we haven't defined. So in that case, we have to change our application , recompile and redeploy. It is not a good idea. If we use delegates in our frameworks, client can add any no of filters without relying on us. See below example. 
  •     public class Photo
        {
            public Photo Load(string path)
            {
                return new Photo();
            }
        }
    	
        public class Filter
        {
            public void Resize(Photo photo)
            {
                Console.WriteLine("Changed the Size");
            }
    
            public void ChangeBrightness(Photo photo)
            {
                Console.WriteLine("Changed the brightness");
            }
    
            public void ChangeContrast(Photo photo)
            {
                Console.WriteLine("Changed contrast of the photo");
            }
    
        }
    	
        public class PhotoMaker
        {
            // Define the delegate
            public delegate void PhotoFilterHandler(Photo photo);
            public void Process(string path, PhotoFilterHandler photofilterhandler )
            {
                var photoObject = new Photo();
                var photo = photoObject.Load(path);
                photofilterhandler(photo);
            }
        }
    	
        class Program
        {
            static void Main(string[] args)
            {
                var photomaker = new PhotoMaker();
                var filter = new Filter();
    			
    	    // Adding ChangeBrightness filter
                PhotoMaker.PhotoFilterHandler filterhandler = filter.ChangeBrightness;
    			
    	    //Adding ChangeContrast filter
    	    filterhandler += filter.ChangeContrast;
    			
    	    // Remove ChangeBrightness filter
                filterhandler -= filter.ChangeBrightness;
    			
    	    //Adding custom method  without changing the PhotoProcess class
                filterhandler+= RemoveRedEye;
               
    	    photomaker.Process("", filterhandler);	
    
                Console.Read();
            }
    
            static void RemoveRedEye(Photo photo)
            {
                Console.WriteLine("Remove Red Eye");
            }
        }
    	
    
  • In .Net, there are two delegates which are generic. They are Action and Func. Difference between Func and Action is Func point to a method that has a return value and Action point to a method that returns void (no return type). 

  • Below code uses in built Action delegate instead of creating a custom delegate. 
  •  	
    public class Photo
        {
            public Photo Load(string path)
            {
                return new Photo();
            }
        }
    	
        public class Filter
        {
            public void Resize(Photo photo)
            {
                Console.WriteLine("Changed the Size");
            }
    
            public void ChangeBrightness(Photo photo)
            {
                Console.WriteLine("Changed the brightness");
            }
    
            public void ChangeContrast(Photo photo)
            {
                Console.WriteLine("Changed contrast of the photo");
            }
        }
    	
        public class PhotoMaker
        {
            public void Process(string path, Action<Photo> photofilterhandler )
            {
                var photoObject = new Photo();
                var photo = photoObject.Load(path);
                photofilterhandler(photo);
            }
        }
    	
        class Program
        {
            static void Main(string[] args)
            {
                var photomaker = new PhotoMaker();
                var filter = new Filter();
    			
                // Adding ChangeBrightness filter
                Action<Photo> filterhandler = filter.ChangeBrightness;
    			
    	    //Adding ChangeContrast filter
    	    filterhandler += filter.ChangeContrast;
    			
    	    // Remove ChangeBrightness filter
                filterhandler -= filter.ChangeBrightness;
    			
    	    photomaker.Process("", filterhandler);	
    
                Console.Read();
            }
        }

  • Use a delegate in the following circumstances:
      • An eventing design pattern is used.
      • The caller has no need to access other properties, methods, or interfaces on the object implementing the method.

      No comments:

      Post a Comment