Generic type factories


Happy new year to everyone! I’ve really got the blog bug over this Christmas period… today, I want to talk a little about how to create easily-consumable generic classes.

Generic Types and Composition

Generics in C# are great. They give so many elegant ways to solve common problems and to implement certain design patterns that without generics would involve lots of boilerplate code. One of the things that they are great at is writing composed objects. For example, let’s say we wanted to represent a binary tree structure in C#. It might look something like this: –

image

Seems logical, doesn’t it? We have our properties which represent the data of a tree node, and a constructor that takes in the item that the node holds. Great – you can now have a tree node for any type e.g. Node<String>, Node<Int32> etc.! However, when you try to start using it and creating nodes in code, you’ll immediately come across a small problem: –

image

See the issue? Every time you want to create a Node of type T, you have to explicitly specify T in the type definition, even though we’re passing in an object of type T into the constructor. Seems a bit pointless, doesn’t it? Can’t the compiler “figure out” the definition from the constructor argument?

Generic methods

Luckily, there is indeed a way to achieve this effect through a generic method which acts as a factory – as long as it does not belong in the generic Node<T> class! Check this guy out: –

image

This method lives in the non-generic Node class. We can easily consume it as follows and thus create nodes much more succinctly: –

image

Sure enough, the nodes are correctly typed just like before e.g. Node<String>, Node<Employee> etc., but now a lot of the fluff has been removed – based on the type of the constructor argument, the return type will be inferred by the compiler. C#’s type inference perhaps isn’t as powerful as F#, but it’s really not that bad Smile

Also notice that we’ve put the factory method in a class called Node – again, this aids the developer in terms of discoverability as it sits alongside Node<TItem>.

Conclusion

You might often find yourself putting generic methods into non-generic classes that themselves return generic objects.

There are many occasions when you may find that you need a non-generic base / sibling class for your generic classes in order to easily construct them, or deal with a set objects of a particular generic type that differ only by their type parameters e.g. Node<String>, Node<Int32> and Node<Employee> – having a non-generic base class called Node with common properties or methods allows you to deal with all instances of all Nodes in one go.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s