How Interfaces, Generics and Extension Methods Can Make Code Cleaner

·

3 min read

From personal experience, one of my biggest gripes when working with code is code duplication. Code duplication makes code appear bloated, harder to read, harder to test and can cause replication of not just the code, but of bugs contain within.

Thankfully, we have three very useful features that individually, and collectively can drastically reduce the amount of code we need to write, and subsequently test.

Lets take a simple list:

List objects = new List { "Hello", 1, "World", 3.4m, DateTime.Now, true};

If we want to get all of the string objects out of the list we could do something like:

List output = new List();
  foreach (object o in objects)
  {
     if(o.GetType() == typeof(string))
     {
       output.Add((string)o);
     }
  }

And then maybe if we needed to do extract the integers from the same list we’d do:

List output2 = new List();
  foreach (object o in objects)
  {
     if(o.GetType() == typeof(int))
     {
       output.Add((int)o);
     }
  }

But already we are almost replicating the code. This is where generics comes in handy. We can convert the same 2 methods into a single method as follows:

public List GetAllOfType(List o)
  {
   List output = new List();
   foreach (object item in o)
   {
      if (item.GetType() == typeof(T))
      {
        output.Add((T)(object)item);
      }
    }
    return output;
  }

And then call the method with:

List strings = GetAllOfType(objects);
List ints = GetAllOfType(objects);

Note: It’s better to cast to object before casting to T as the compiler always knows the route from object to T, but can sometimes protest casting directly from one object to T without the intermediary step. In the above example it’s not essential.

Now we have the method, it would make sense to make the method available from any class rather than just in the class we’re using. This allows maximum reuse, again meaning we’ll not need to replicate this. To do this we create an extension method by creating a new static class, and placing the method in there, making sure the method is also static and adding the ‘this’ keyword to the List parameter:

public static List GetAllOfType(this List o)
  {
    List output = new List();
    foreach(object item in o)
    {
      if(item.GetType() == typeof(T))
      {
        output.Add((T)(object)item);
      }
    }
    return output;
  }

As you will, we can now see this method appear in our intellisense:

ext1.jpg

Notice we now call the method on the original list rather than pass the collection as the argument.

So now we have an extension method available to retrieve all objects of a certain type from a list.

However, we can still improve this through the use of interfaces. Suppose we want to be able to retrieve all objects of a type from an array for example. Rather than creating a separate extension method for an array, we can remove the reference to the list and replace it with a reference to the IEnumerable interface, which is implemented both by a List and an array, along with many other collections:

public static IEnumerable GetAllOfType(this IEnumerable o)
  {
     List output = new List();
     foreach(object item in o)
     {
          if(item.GetType() == typeof(T))
          {
              output.Add((T)(object)item);
          }
      }
      return output;
  }

We can now user the same extension method for lists and arrays as follows:

List objectList = new List { "Hello", 1, "World", 3.4m, DateTime.Now, true};
  object\[\] objectArray = new object\[\] { "Hello", 1, "World", 3.4m, DateTime.Now, true };
  IEnumerable strings = objectList.GetAllOfType();
  IEnumerable ints = objectArray.GetAllOfType();

Clearly this is a very simplistic example, but as you can see, mixing interfaces, generics and extension methods can create very concise flexible code. The above example doesn’t need to be taken much further to become very useful when working with abstract classes.

The post How Interfaces, Generics and Extension Methods Can Make Code Cleaner appeared first on Talking I.T. Through.

Did you find this article valuable?

Support Dave K by becoming a sponsor. Any amount is appreciated!