Register Now | Sign In
FeedGhost Logo

RSS feed Stu Smith: Making It Up As I Go Along

My life working for BinaryComponents, coding, design, and other stuff.


Lee and I are working on a project at the moment, and we got into a mini-argument about how best to write a tiny piece of code. Essentially, we're working with a thrid-party API that returns some data as key/value pairs in a hastable: the keys are always strings, but the values can be either strings, or further hashtables. (So essentially we have a tree structure). For the purposes of this discussion, we need to render that tree as XML.

Here's the "traditional" method of accomplishing this:

public static XDocument ConvertDictionaryToXml( IDictionary dictionary )
{
 XElement root = new XElement( "root" );

 ConvertDictionaryToXml( root, dictionary );

 return new XDocument( root );
}

public static void ConvertDictionaryToXml( XElement parent, IDictionary dictionary )
{
 foreach( DictionaryEntry kv in dictionary )
 {
  XElement newElement = new XElement( kv.Key.ToString() );

  if( kv.Value is IDictionary )
  {
   ConvertDictionaryToXml( newElement, (IDictionary)kv.Value );
  }
  else
  {
   newElement.Value = kv.Value.ToString();
  }
  parent.Add( newElement );
 }
}

Now I disagree with this - it's my belief that loops should go the way of the "goto" statement and be consigned to history. Here's my version:

public static XDocument ConvertDictionaryToXml( IDictionary dictionary )
{
 var root = new XElement( "root", DictionaryToXElement( dictionary ) );

 return new XDocument( root );
}

private static XElement[] DictionaryToXElement( IDictionary sourceDictionary )
{
 var xelements = from DictionaryEntry p in sourceDictionary
   let dp = p.Value as IDictionary
   select (dp == null)
    ? new XElement( p.Key.ToString(), p.Value.ToString() )
    : new XElement( p.Key.ToString(), DictionaryToXElement( dp ) );

 return xelements.ToArray();
}

Short and sweet. No (visible) changing state to understand, just a recursive sequence transform. I see parallels here in the new WPF model of animation: in the older WinForms, to animate something, you'd set up a timer and repeatedly change it. In the newer WPF, you simply set up the intent of the animation, and the system handles the messy updating stuff.

I see it as a natural progression in the power of languages:

  • C# 1.0 - zero-dimensional. Language support limited to operations on single data items.
  • C# 3.0 - one-dimensionalLanguage supports operations on sequences of data items.
  • C# N.0 - two-dimensional. Language supports operations on trees/graphs of data items.

(Incidentally, I'm well aware of the similarities to languages like LISP or Haskell - and if you think LISP is old-fashioned, you should probably have a read of Structure and Interpretation of Computer Programs).

If you're worried about performance, well, I guess there could be a hit with my version, you'd have to profile it, but on the other hand the LINQ version would parallelize nicely using PLINQ, something that can't be said for arbitrary for-loops. (Of course, if we were worried about performance, we wouldn't be using XML).

FeedGhost - Professional RSS Reading




What do you think?

Your name: (optional)
Comment: (no HTML please)
Enter the numbers: Security Code