C# Case Study – Delegate as a Method in Practice

Case Background

A courier company ships parcels in the local area. There are four zones in the company’s business area. The shipping fees are a certain percentage of the given item price. Some destinations are a bit dangerous or far from the company’s depot, which has an additional risk fee $25.

  • Zone 1 – 25%
  • Zone 2 – 12%. Zone 2 is a dangerous area and it imposes $25.
  • Zone 3 – 8%
  • Zone 4 – 4%. Zone 4 is a dangerous area and it imposes $25.

Approach

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

namespace DelegatesSolution
{
    class Program
    {
        static void Main(string[] args) {

            ShippingFeesDelegate theDel;
            ShippingDestination theDest;

            string theZone;
            do {              
                Console.WriteLine("What is the destination zone?");
                theZone = Console.ReadLine();

                if (!theZone.Equals("exit")) {               
                    theDest = ShippingDestination.getDestinationInfo(theZone);
                  
                    if (theDest != null) {
                        
                        Console.WriteLine("What is the item price?");
                        string thePriceStr = Console.ReadLine();
                        decimal itemPrice = decimal.Parse(thePriceStr);

                        theDel = theDest.calcFees;

                        if (theDest.m_isHighRisk) {
                            theDel += delegate(decimal thePrice, ref decimal itemFee) {
                                itemFee += 25.0m;
                            };
                        }

                        //CALCULATION STARTS FROM HERE
                        decimal theFee = 0.0m;
                        theDel(itemPrice, ref theFee);
                        Console.WriteLine("The shipping fees are: {0}", theFee);
                    }
                    else {
                        Console.WriteLine("Hmm, you seem to have entered an uknown destination. Try again or 'exit'");
                    }
                }
            } while (theZone != "exit");
        }
    }
}

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

namespace DelegatesSolution
{
    
    public delegate void ShippingFeesDelegate(decimal thePrice, ref decimal fee);

    abstract class ShippingDestination
    {
        public bool m_isHighRisk;
        public virtual void calcFees(decimal price, ref decimal fee) {}

        
        public static ShippingDestination getDestinationInfo(string dest) {
            if (dest.Equals("zone1")) {
                return new Dest_Zone1();
            }
            if (dest.Equals("zone2")) {
                return new Dest_Zone2();
            }
            if (dest.Equals("zone3")) {
                return new Dest_Zone3();
            }
            if (dest.Equals("zone4")) {
                return new Dest_Zone4();
            }
            return null;
        }
    }

    class Dest_Zone1 : ShippingDestination
    {
        public Dest_Zone1() {
            this.m_isHighRisk = false;
        }
        public override void calcFees(decimal price, ref decimal fee) {
            fee = price * 0.25m;
        }
    }

    class Dest_Zone2 : ShippingDestination
    {
        public Dest_Zone2() {
            this.m_isHighRisk = true;
        }
        public override void calcFees(decimal price, ref decimal fee) {
            fee = price * 0.12m;
        }
    }

    class Dest_Zone3 : ShippingDestination
    {
        public Dest_Zone3() {
            this.m_isHighRisk = false;
        }
        public override void calcFees(decimal price, ref decimal fee) {
            fee = price * 0.08m;
        }
    }

    class Dest_Zone4 : ShippingDestination
    {
        public Dest_Zone4() {
            this.m_isHighRisk = true;
        }
        public override void calcFees(decimal price, ref decimal fee) {
            fee = price * 0.04m;
        }
    }
}

Study Note

In the Program.cs, we use a basic structure as logic to implement the solution. The do-while ensures the program running till use type in exit.

string theZone;
do {
//Implementation
} while(theZone != "exit");

In the do-while statement, we retrieve a ShippingDestination object to represents a shipping zone. How do we do that? Have a look the following code snippet in ShippingInfo.cs

abstract class ShippingDestination
    {
        public bool m_isHighRisk;
        public virtual void calcFees(decimal price, ref decimal fee) {}

        
        public static ShippingDestination getDestinationInfo(string dest) {
            if (dest.Equals("zone1")) {
                return new Dest_Zone1();
            }
            if (dest.Equals("zone2")) {
                return new Dest_Zone2();
            }
            if (dest.Equals("zone3")) {
                return new Dest_Zone3();
            }
            if (dest.Equals("zone4")) {
                return new Dest_Zone4();
            }
            return null;
        }
    }

We use keyword abstract to declare an abstract class to prevent it from being instantiated by itself. We can’t create a ShippingDestination class object; we have to create a subclass to represent a zone. This is an excellent approach for the cleaning code practice.

As a result, when user types in a zone, we will have a designated zone object as a subclass object of ShippingDestination class.

In regard to shipping fee calculation, we use a delegate to calculate and manipulate the shipping fee for us. How?

In each of the ShippingDestination’s subclass, we have a method called public override void calcFees(decimal price, ref decimal fee). It shares the same signature with delegate public delegate void ShippingFeesDelegate(decimal thePrice, ref decimal fee).

We use a reference variable so that we can return the calculated value and it can be further manipulated by another delegate.

In the Program.cs file, we assign a specific zone’s fee calculate method to our delegate. It passes a reference variable, which can be further manipulated if needed.

When we need to calculate the fee in a dangerous area, we use an anonymous delegate in line to further modify shipping fee to include an additional $25.

theDel = theDest.calcFees;
if (theDest.m_isHighRisk) {
     theDel += delegate(decimal thePrice, ref decimal itemFee) {
           itemFee += 25.0m;
         };
}

In the end, we define a local variable that will hold the result, then we invoke the delegate.

decimal theFee = 0.0m;
theDel(itemPrice, ref theFee);
Console.WriteLine("The shipping fees are: {0}", theFee);

Delegate is a heavily used techniques in development, it can take time to sink in. Good Luck 🙂 Happy programming.


18 Replies to “C# Case Study – Delegate as a Method in Practice”

  1. I’m just commenting to let you be aware of of the fabulous discovery my cousin’s daughter experienced going through your site. She even learned lots of issues, most notably how it is like to have a very effective giving mindset to have many others just gain knowledge of chosen grueling matters. You really did more than our desires. Many thanks for distributing the important, healthy, educational and as well as easy thoughts on the topic to Gloria.

  2. I enjoy you because of all of your efforts on this site. Ellie enjoys doing internet research and it’s easy to see why. All of us hear all concerning the compelling manner you deliver functional ideas by means of the blog and as well cause contribution from other people about this concept plus my daughter is being taught a lot. Enjoy the remaining portion of the new year. You’re the one carrying out a first class job.

  3. I am glad for writing to make you know what a magnificent encounter my wife’s girl had studying your web site. She mastered several pieces, which include what it’s like to possess an awesome helping nature to let other individuals very easily know precisely some multifaceted subject matter. You truly exceeded people’s expectations. Thank you for presenting these powerful, trusted, informative and in addition fun tips about this topic to Kate.

  4. I am glad for writing to make you know what a incredible encounter my friend’s girl gained studying your web page. She learned plenty of pieces, which include what it’s like to possess an awesome helping mood to let other folks smoothly know just exactly several multifaceted subject matter. You truly exceeded our own expectations. Thank you for offering these necessary, safe, explanatory and even fun tips about this topic to Julie.

Leave a Reply

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