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!!!