Extension methods using C#

During my time working, I find that developers can get lazy and start using the COPY and PASTE commands to a degree that can make code unmanageable.

There are many things we can do to reduce, if not eliminate, the code management nightmare, however, the one way I will focus on is using extension methods.

So what are extension methods ? and why should we use extension methods ? Let’s try to answer these questions in a scenario.

Let us assume we have a type, and this type is called “Int”, in our application we use our Int types A LOT.
We find that we either keep re-coding certain snippets of code or just lazily applying the copy, paste and replace procedure in order to complete or patch our application.
Now what happens when that logic has a bug or needs to be changed ? would you go to each implementation and fix it ? wouldn’t life be easier if this piece of logic could be changed in just one place ?

I’m not saying the using extension methods is the ONLY approach, but it is the approach we will be going through.

Here are a few rules before we go on to the code:

  1. your extension classes should be public and static
  2. your extension methods should be public and static

Let’s assume we had an array of integers:

1
2
3
4
int[] numbers = new int[]
{
    1, 3, 5, 6, 8, 9, 10
};

We needed to loop through this list of integers and determine if each number is even or odd, additionally we needed to determine if each number is a prime number or not.
Lets attempt to code this without using extension methods (the not so manageable approach).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
int[] numbers = new int[]
{
    1, 3, 5, 6, 8, 9, 10
};
 
foreach(int i in numbers)
{
    Console.WriteLine(i.ToString());
    bool isEven = ((i % 2) == 0);
    if(isEven)
    {
        Console.WriteLine("\tEven");
    }
    else
    {
        Console.WriteLine("\tOdd");
    }
 
    if(i == 1)
    {
        Console.WriteLine("\tNot Prime");
    } else if (i == 2)
    {
        Console.WriteLine("\tIs Prime");
    }
    else
    {
        bool isPrime = true;
        double boundry = Math.Floor(Math.Sqrt(i));
 
        for (int j = 2; j <= boundry; ++j)
        {
            if ((i % j) == 0)
            {
                Console.WriteLine("\tNot Prime");
                isPrime = false;
                break;
            }
        }
 
        if(isPrime)
        {
            Console.WriteLine("\tIs Prime");
        }
    }
}

notice how long and messy this code looks ? using extension methods we can make this code more elegant and managable.

lets start of by creating a new class file and we can call this “SimpleExtenionMethods.cs”
this class should contain the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ExtensionMethodSample
{
    public static class SimpleExtensionMethods
    {
        public static bool IsEven(this int i)
        {
            return ((i % 2) == 0);
        }
 
        public static bool IsPrimeNumber(this int i)
        {
            if (i == 1) return false;
            if (i == 2) return true;
 
            double boundry = Math.Floor(Math.Sqrt(i));
 
            for(int j = 2; j  <= boundry; ++j)
            {
                if ((i % j) == 0) return false;
            }
 
            return true;
        }
    }
}

and here’s the implementation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// number array
int[] numbers = new int[]
{
    1, 3, 5, 6, 8, 9, 10
};
 
// out each result
foreach(int i in numbers)
{
    Console.Write("Testing #" + i.ToString() + ":\t");
 
    if(i.IsEven())
    {
        Console.Write("Evem");
    }
    else
    {
        Console.Write("Odd");
    }
 
    if(i.IsPrimeNumber())
    {
        Console.Write( ", Prime Number");
    }
 
    Console.WriteLine();
}

is that not so much simpler, elegent and far more readable ?

here’s the result:

Testing #1:     Odd
Testing #3:     Odd, Prime Number
Testing #5:     Odd, Prime Number
Testing #6:     Even
Testing #8:     Even
Testing #9:     Odd
Testing #10:    Even

lets take this step further, what if we wanted to split the ODD and EVEN numbers into seperate list objects ?
lets create a new class file called “SlightlyComplexExtensions.cs”
the code should be as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ExtensionMethodSample
{
    public static class SlightlyComplexExtensions
    {
        public static Dictionary<string, List<int>> SplitNumbersIntoSections(this int[] iArr)
        {
            Dictionary<string, List<int>> result = new Dictionary<string, List<int>>();
            result.Add("Odd", new List<int>());
            result.Add("Even", new List<int>());
 
            foreach(int i in iArr)
            {
                if(i.IsEven())
                {
                    result["Even"].Add(i);
                }
                else
                {
                    result["Odd"].Add(i);
                }
            }
 
            return result;
        }
    }
}

and here’s the implementation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// number array
int[] numbers = new int[]
{
    1, 3, 5, 6, 8, 9, 10
};
 
// split array into sections
Dictionary<string, List<int>> numberSplit = numbers.SplitNumbersIntoSections();
 
// out each section
foreach(string key in numberSplit.Keys)
{
    // key will either be EVEN or ODD
    Console.WriteLine(key + ":");
 
    // out the numbers in the section
    foreach(int i in numberSplit[key])
    {
        Console.WriteLine("\t" + i.ToString());
    }
}

here’s the result:

Odd:
        1
        3
        5
        9
Even:
        6
        8
        10

Let us now take this one more step further, we now wish to generate a third list containing the prime numbers, this can be done without changing the implementation code. All that changes is the extension method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ExtensionMethodSample
{
    public static class SlightlyComplexExtensions
    {
        public static Dictionary<string, List<int>> SplitNumbersIntoSections(this int[] iArr)
        {
            Dictionary<string, List<int>> result = new Dictionary<string, List<int>>();
            result.Add("Odd", new List<int>());
            result.Add("Even", new List<int>());
            result.Add("Prime", new List<int>());
 
            foreach(int i in iArr)
            {
                if(i.IsEven())
                {
                    result["Even"].Add(i);
                }
                else
                {
                    result["Odd"].Add(i);
                }
 
                if(i.IsPrimeNumber())
                {
                    result["Prime"].Add(i);
                }
            }
 
            return result;
        }
    }
}

here’s the result:

Odd:
        1
        3
        5
        9
Even:
        6
        8
        10
Prime:
        3
        5