Generic Calculator

In this article I shall demonstrate how to use Generics in developing a sample calculator application.

Before going through this article I strongly recommend to go through the basics of Generics in C#. There are lot of articles in c-sharpcorner.com.

In order to demonstrate, I have developed a console application.

In this sample it is possible to perform mathematical operations for any number of inputs.

Step 1: Create an abstract class as shown

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


namespace GenericCalculator

{

       public abstract class AbstractCalculator<T>
    {
        public abstract T Add(T input1, T input2);
        public abstract T Sub(T input1,T input2);

        public abstract T Multiply(T input1,T input2);
        public abstract T Divide(T input1,T input2);
    }

}


This class takes a generic data type.

Step 2: Create an IntCalculator class which performs all actions with integer as inputs.

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


namespace
GenericCalculator

{
    public class IntCalculator : AbstractCalculator<int>
    {
        public override int Add(int input1, int input2)
        {
            return input1 + input2;
        }

        public override int Sub(int input1, int input2)
        {
            return input1 - input2;
        }

        public override int Multiply(int input1, int input2)
        {
          
            return input1 * input2;
        }

        public override int Divide(int input1, int input2)        {
            return input1 / input2;
        }

    }
}

Step 3: Create a DoubleCalculator class which performs all actions with double as inputs.

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


namespace
GenericCalculator

{
    class DoubleCalculator:AbstractCalculator<double>
    {
        public override double Add(double input1, double input2)
        {
            return input1 + input2;
        }
       public override double Sub(double input1, double input2)
        {
            return input1 - input2;
        }

        public override double Multiply(double input1, double input2)
        {
            return input1 * input2;
        }


        public override double Divide(double input1, double input2)
        {
            return input1 / input2;
        }
    }
}


Like the same way we can create classes for decimal, float etc.

Step 4: Create a class which performs the various actions in a calculator based on the incoming input parameters as shown.

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

namespace GenericCalculator
{
   public class ArithmeticOperation <T>

    {
       AbstractCalculator<T> _myCalculator;


       public ArithmeticOperation(AbstractCalculator<T> myCalculator)
       {
           this._myCalculator = myCalculator;
       }
       public T Sum(List<T> items)
       {
           dynamic sum=0;

           for (int i = 0; i < items.Count; i++)
           {
               sum = _myCalculator.Add(sum, items[i]);
           }


           return sum;
       }

       public T Sub(List<T> items)
       {
           dynamic sub = 0;
           for (int i = 0; i < items.Count; i++)
           {
               sub = _myCalculator.Sub(sub, items[i]);
           }
           return sub;
       }

       public T Multiply(List<T> items)
       {
           //val is set to 1 for the first multiplication attempt.
          dynamic mul=1;
         
          for (int i = 0; i < items.Count; i++)
           {
               mul = _myCalculator.Multiply(mul, items[i]);
           }
           return mul;
       }
       public T Divide(List<T> items)
       {
           dynamic div = 1;
           for (int i = 0; i < items.Count; i++)
           {
               if (div == 1)
               {

                   // Initially the val is set to one and the first value in items collection is set as the
first parameter to didvide function.


                   div = _myCalculator.Divide(items[i], div);
               }
               else

               {
                   div = _myCalculator.Divide(div, items[i]);

               }
           }

           return div;
       }      
    }
}


This class has got a parameter of type AbstractCalculator in its constructor. Any class which inherits this abstract class can be passed as parameter to the constructor of this class.

All the mathematical functions accept a List<T> collection.

Step 5: Client Code (Console Application)

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

namespace GenericCalculator
{
    class Program
    {
        static void Main(string[] args)
        {
            ArithmeticOperation<int> intOperation = new ArithmeticOperation<int>(new IntCalculator());
            ArithmeticOperation<double> doubleOperation = new ArithmeticOperation<double>(new DoubleCalculator());
            List<int> numbers = new List<int> {1,2,3,4,5 };

            List<double> doubleNumbers = new List<double> {1.1, 2.2, 3.3, 4.4, 5.5};
            Try
            {
                Console.WriteLine("Integer Calculation");

                Console.WriteLine("************************************************************");
                Console.WriteLine("Addition : {0}", intOperation.Sum(numbers));
                Console.WriteLine("Substraction : {0}", intOperation.Sub(numbers));
                Console.WriteLine("Mulitplication : {0}", intOperation.Multiply(numbers));
                Console.WriteLine("Division : {0}", intOperation.Divide(numbers));

              Console.WriteLine("************************************************************");
               Console.WriteLine("Double Calculation");

            Console.WriteLine("*********************************************************
**"
);
                Console.WriteLine("Addition : {0}", doubleOperation.Sum(doubleNumbers));
                Console.WriteLine("Substraction : {0}", doubleOperation.Sub(doubleNumbers));
                Console.WriteLine("Mulitplication : {0}", doubleOperation.Multiply(doubleNumbers));
                Console.WriteLine("Division : {0}", doubleOperation.Divide(doubleNumbers));

            }
            catch (DivideByZeroException ex)
            {
                Console.WriteLine("Division Error : {0}", ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(" Error : {0}", ex.Message);
            }

            Console.ReadLine();
        }
    }
}


ArithmeticOperation<int> intOperation = new ArithmeticOperation<int>(new IntCalculator());

 To the constructor of ArithmeticOperation class an instance of the IntCalculator class is passed as the ArithmeticOperation class is of an integer data type.

ArithmeticOperation<double> doubleOperation = new ArithmeticOperation<double>(new DoubleCalculator());

To the constructor of ArithmeticOperation class an instance of the DoubleCalculator class is passed as the ArithmeticOperation class is of a double data type.

For a better understanding I have shared the source code.

Output

Happy Coding!!!