Passing TYPE around in C# (Generics)

Yesterday when I was doing a code review for one of my co-worker, I saw a scenario where there were two methods, where both the method does the same thing except for each one different types. It is a silverlight code, where he need to find a grid and another child element. By looking at the code, it begs refactoring, he was able to refactor the code easily with generics. When we did the refactor, I was wondering if there is another way of doing it without generics and it is. So here are the two ways to pass the types around and perform your check in a common function.

For our discussion we are going to have a heterogeneous collection, where we will an element of String, int, float and a List of int, like the following

genericList.Add("Unni");
genericList.Add(10);
genericList.Add(99.99);
List<int> tempList = new List<int>() { 2, 3 };
genericList.Add(tempList);

next we are going to write a method which will accept a TYPE as input and check if the type exists in the collection. The first and simple approach is by  passing the type itself as a parameter as shown below

public object CheckType(Type type)
{
    foreach (var t in genericList)
    {
        if (type.IsInstanceOfType(t))
            return t;
    }
    return -99;
}

Here is the associated test for his method

[Test]
public void It_Can_Return_10_When_int()
{
    Class1 c1 = new Class1();
    Assert.AreEqual(10, c1.CheckType(typeof(int)));
}

We walk though the collection and check each element is instance of a required type we need to find. If we find it, it will return the element from the collection. Now lets look at the second option using generics as it is supposed to be written

public object CheckType<T>()
{
    foreach (var t in genericList)
    {
        if (t is T)
            return t;
    }
    return -99;
}

and associated Tests

[Test]
public void It_Can_Return_10_When_int_As_T()
{
    Class1 c1 = new Class1();
    Assert.AreEqual("Unni", c1.CheckType<string>());
}

[Test]
public void It_Can_Return_List_When_List()
{
    Class1 c1 = new Class1();
    List<int> tempList = new List<int>() { 2, 3 };
    Assert.AreEqual(tempList, c1.CheckType<List<int>>());
}

We create a method and pass generic type T. Now the code which this is very elegant because you do not pass the type as the input parameter.

Advertisements