Wednesday 2 June 2010

Platform evolution and inconsistencies

It's not easy to evolve a platform, avoid breaking code and being consistent.

So far, one of the main changes undergone by the .Net Framework was the inclusion of generics both at the CLR level and the language level.

With this, we saw the arrival of a common creational idiom:


T Create<T>(){/*implementation here*/}
T myObject = Factory.Create<T>();


so, we can write code like this:


MyType instance = Factory.Create<MyType>();


instead of this


(MyType) instance = Factory.Create(typeof(MyType));
//note the need of a casting due to a method signature like this:
Object Create(Type t){/*implementation here*/}


We have a sample of both styles in Activator.CreateInstance, which among other overloads has:

  • public static Object CreateInstance(Type type) //old style, available since framework 1

  • public static T CreateInstance<T>() //new style, available since framework 2.0


Note that version 1 is not marked as deprecated. That makes some sense due to its dynamic nature. Doing a CreateInstance(otherInstance.GetType) means that we don't need to know at compile time (as happens with the generic version) the type of the object to create. Anyway, we would be returning an Object, and as we could not cast it (cause we don't know what to cast to) it would not be much usable (only through Introspection). In .Net 4, the dynamic keyword would make it more convenient to use.

Today, when checking more in depth the list of new features in .Net I came across something that looked a bit inconsistent to me. We have a new Enum.TryParse that is rather welcome and uses the second style, but when compared with "classic" Enum.Parse that uses the first style, the whole picture looks a bit inconsistent:

Parse(Type, String)
Parse(Type, String, Boolean)

TryParse<TEnum>(String, TEnum)
TryParse<TEnum>(String, Boolean, TEnum)

in this case, given that I don't think that there's any dynamic scenario that needs of a Parse(myInstance.GetType(),...), I believe the best would have been marking the current Parse implementations as deprecated and add 2 new ones:

Parse<TEnum>(String)
Parse<TEnum>(String, Boolean)

No comments:

Post a Comment