Mar 14

Generics: open vs closed types

Posted in Basics C# CLR      Comments Off on Generics: open vs closed types

Before going on, does anyone know how to improve the performance of Windows Live Writer? It’s painfully slow after I’ve updated it to the latest release and it’s upsetting me a lot. I’ve tried to disable everything, but the damn app doesn’t show any improvements…damn…ok, enough bitching…

In the previous post, I’ve introduced generics. In this post, we’ll keep looking at generics and I’ll present the concept of open vs. closed type. Before going on, let’s recover the MyList snippet I’ve introduced in the previous post:

class MyList<T> {
    public void Add(T item) {
    public void Remove(T item) {
    public void Sort(IComparer<T> comparer) { }

And then there was some code which used MyList with ints:

var intList = new MyList<Int32>();

And now, we’re ready to proceed Smile

As you probably know,the CLR uses internal data structures for every type used by an application. These data types are generally known as type objects. Generics are also types and that’s why it shouldn’t surprise you to find out that they too have their own type objects. In other worlds,MyList<T>  is a type and you can get its type object. However, there’s an important difference between MyList<T> and, say, String: you cannot instantiate a generic type without specifying a data type for its type parameter. That’s why we had to pass Int32  when we instantiated MyList in the previous snippet.

Btw, a type with generic type parameters is called an open type. Whenever code  references a generic type and replaces its generic type argument with a specific type, we end up with what is known as a closed type (notice that closed types are only obtained when all generic type arguments are replaced with concrete types; if that doesn’t happen, then you’re just creating a new open type). An interesting way to see the difference between open and closed types is to print the information returned by the typeof operator to the console:


The previous snippet ends up printing the following:


The astute reader will probably notice the backtick followed by a number…the number represents the type’s arity, which is used for indicating the number of type parameters of that type. In our example, MyList arity 1 because it only has one type argument. Another interesting conclusion is that the closed type will share eventual static fields with all instances of that closed type (in our case, it MyList<T> introduced a static field, then MyList<Int32> is a closed type with its own static fields which aren’t shared with, say, MyList<String>).

Being a type, it’s also possible to use a generic type (open or closed) as a base type or to build a new generic type which extends an existing type. Before ending, time for one last gotcha: I’ve noticed that some developers prefer to do this:

class IntList : MyList<Int32> { }

instead of instantiating MyList<Int32> directly like I did in the previous snippets. Please, don’t do this. The problem with this approach is that IntList is a different type from MyList<Int32>:

Console.WriteLine(typeof(IntList) == typeof(MyList<Int32>));

The previous snippet prints false because we’re talking about types with different identities! If you prefer the last approach because it saves a few keystrokes, then don’t forget that you can use the var approach or even create an alias through the using keyword. And that’s it for now. Stay tuned for more.