TypeConverters: There's not enough TypeDescripter.GetConverter in the world
While reading source today, I saw some code in the wild today that looked roughly like this (not the actual code):
type = typeof(T);
if (type == typeof(Boolean))
returnValue = (T)((object)Convert.ToBoolean(value));
else if (type == typeof(String))
returnValue = (T)((object)value);
else if (type == typeof(Int16))
returnValue = (T)((object)Convert.ToInt16(value));
else if (type == typeof(Int32))
returnValue = (T)((object)Convert.ToInt32(value));
//...and on and on for a dozen+ types
You get the idea. This isn't that uncommon, I've seen it more of than not. The person who is writing it usually knows it's bad 50% of the time, but it's always a trade-off between figuring out the right search query (a tough one, in this case!) and knowing what to look for in MSDN.
This brings up one of my favorite classes in the BCL, the TypeDescriptor class. A method like this:
public static T GetTfromString<T>(string mystring)
var foo = TypeDescriptor.GetConverter(typeof(T));
...would allow all that switch/if/else to go away replaced by:
bool b = GetTfromString
You'd probably want to expand the method with checks to see if T was in fact, System.Type, or System.String, but you get the idea.
There are lots of standard converters like EnumConvertor, ColorConvertor, and more, all waiting for you in System.ComponentModel as seen in the image at right.
Not only that, but you can make your own TypeConverters and spread the love. They are used extensively when displaying types in Property Grids, in WinForms, or in XAML. You can also use them in PowerShell as a better way to present your objects as strings when "casting" in PowerShell.
Jesse Liberty has a fine example showing how to use Type Convertors in Silverlight to enable you to put complex types in XAML attributes.
To implement a simple type converter that can translate a string to a [Type]
Define a class that derives from TypeConverter.
Override the CanConvertFrom method that specifies which type the converter can convert from. This method is overloaded.
Override the ConvertFrom method that implements the conversion. This method is overloaded.
Override the CanConvertTo method that specifies which type the converter can convert to. It is not necessary to override this method for conversion to a string type. This method is overloaded.
Override the ConvertTo method that implements the conversion. This method is overloaded.
Override the IsValid method that performs validation. This method is overloaded.
That's it, and when that Type was decorated with an attribute like:
Then that new TypeConverter would be picked up and used by the line of code I showed before. Much better than a switch or pile of if/elses, I think.