Sometimes you need to be able to convert between multiple data types. One solution is to create a "universal type converter," which is an object that implicitly executes all of the desired type conversions.
![]()
Example
The best way to illustrate this is with an example. Assume we have a simple object class "Obj" that can contain multiple dynamic properties, defined by the "Prop" class. (By "dynamic" I mean the properties can be created at run-time, rather than at compile time as is typical with C# properties). Each dynamic property has a "Name" and "Value" and is stored in a Dictionary indexed by the property's Name. The "GetProp" method returns an existing property or creates a new property if needed. For simplicity, error checking is omitted and public fields are used.
public class Obj { private Dictionary<string, Prop> m_Props = new Dictionary<string, Prop>(); public Prop GetProp( string propName ) { Prop prop = null; if (!this.m_Props.TryGetValue( propName, out prop )) { prop = new Prop(); prop.Name = propName; this.m_Props.Add( propName, prop ); } return prop; } } public class Prop { public string Name; public object Value; }
Using a Universal Type Converter
Let's say we want to get and set the dynamic property values with an easy syntax–using the object's index operator []. For example, consider this console program that creates two of our objects, sets their dynamic property values, then gets and writes the property values to the console window:
class Program { static void Main( string[] args ) { Obj obj = new Obj(); obj["Name"] = "Joe"; obj["Age"] = 27; obj["StartDate"] = new DateTime( 2002, 9, 8 ); Write( obj ); obj["Name"] = "Mike"; obj["Age"] = 34; obj["StartDate"] = new DateTime( 2005, 12, 5 ); Write( obj ); Console.ReadLine(); } static void Write( Obj obj ) { string name = obj["Name"]; int age = obj["Age"]; DateTime startDate = obj["StartDate"]; Console.WriteLine( "name={0} age={1} start={2:d}", name, age, startDate ); } }
How would you accomplish this? It's not as easy as it looks. Fire up a Visual Studio console project and test your C# skills. Then return here to see how you can solve this challenge with a universal type converter.
(waiting…)
Building a Universal Type Converter
Welcome back (if you left). How did you do?
For our universal type converter (UTC) we define the "PropValue" class, which represents a property value. This class converts any of our supported types into a property value and vice-versa. To keep this example simple, we will only support values that have a DateTime, integer or string type, but naturally you could extend this UTC to include any native C# types or other types that you have defined. Here is the full class:
public class PropValue { #region CONSTRUCTORS public PropValue( object value ) { this.m_Value = value; } public PropValue( Obj obj, string propName ) { this.m_Obj = obj; this.m_PropName = propName; } #endregion CONSTRUCTORS #region VALUE private object m_Value; public object Value { get { return this.m_Value; } } #endregion VALUE #region PROPERTY private string m_PropName; private Obj m_Obj; private Prop GetProp() { return this.m_Obj.GetProp( this.m_PropName ); } #endregion PROPERTY #region CONVERTERS #region FROM VALUE public static implicit operator DateTime( PropValue propVal ) { object value = propVal.GetProp().Value; return value is DateTime ? (DateTime)value : DateTime.MinValue; } public static implicit operator int( PropValue propVal ) { object value = propVal.GetProp().Value; return value is int ? (int)value : 0; } public static implicit operator string( PropValue propVal ) { object value = propVal.GetProp().Value; return value is string ? (string)value : null; } #endregion FROM VALUE #region TO VALUE public static implicit operator PropValue( DateTime val ) { return new PropValue( val ); } public static implicit operator PropValue( int val ) { return new PropValue( val ); } public static implicit operator PropValue( string val ) { return new PropValue( val ); } #endregion TO VALUE #endregion CONVERTERS }
Notice the conversion operators that go both ways for each type: PropValue <–> DateTime, PropValue <–> integer, and PropValue <–> string. Also notice the two constructors: one that accepts a value, another that accepts the Obj and Prop name that identifies the property.
Of course, we also need to add the index operator [] to the Obj class. The get-block returns the value in its native type. The set-block finds the appropriate Prop dynamic property and sets its Value:
public PropValue this[string propName] { get { return new PropValue( this, propName ); } set { Prop prop = this.GetProp( propName ); prop.Value = value.Value; } }
Note that you can improve efficiency by moving the UTC inside the Prop class. This eliminates the need to create a PropValue object each time you get or set a property value. However, there may be times you do not want the Prop class itself to have UTC capability, in which case a separate converter class is necessary, as shown in this example.
Popularity: 20% [?]
Copyright © 2007-8 Tiwebb Ltd. All rights reserved. This material may not be published, broadcast, rewritten or redistributed without explicit permission from Tiwebb Ltd.

