Thursday, November 22, 2007

C#3.0 ToXml Extension Method

I know I stated in my last post I was going to work on extension methods for DateTime. However sometimes you do not know when an idea is going to spark your interest. I have this project where I am building business classes that inherited from a base class which has a method on it to allow the inherited classes to be converted to Xml via the .Net Xml Serialization functionality. As I was working with extensions I had the idea of creating that method as an extension method so it could be used by any data type.

The code is really quite simple. I set the first argument as object, so all types can reference the method. After that it just calls into the XmlSerialization classes to perform the conversion. Code is written C#. The previous post explains how to write extension methods in VB

You will need to add these namespaces.


using System.IO;
using System.Xml.Serialization;


Method Source Code

public static class XmlConvertExtensions
{
 public static string ToXml(this object obj)
  {
  XmlSerializer s = new XmlSerializer(obj.GetType());
  using (StringWriter writer = new StringWriter()) {
   s.Serialize(writer, obj);
   return writer.ToString();
  }
  }
}


Example showing the extension in action:

string input = "hello world";
string xmlData = input.ToXml();


That’s cool, but how can we get it back from Xml? Add this class. It has generic support to convert an Xml string back to a data type.

public class FromXml<T>
{
  public T Convert(string data)
  {
   XmlSerializer s = new XmlSerializer(typeof(T));
   using (StringReader reader = new StringReader(data))
   {
    object obj = s.Deserialize(reader);
    return (T)obj;
   }
  }
}

Example showing moving a string to and from Xml.

string input = "hello world";
string xmlData = input.ToXml();
string backFromXml = new FromXml<string>().Convert(xmlData);


Update
Thanks to the comment from Steve for the suggestion of moving the conversion from an Xml string onto the string class as an extension method. It is a much cleaner solution than what I first had.

public static class FromXmlExt
{
  public T FromXml<T>(this string data)
  {
   XmlSerializer s = new XmlSerializer(typeof(T));
   using (StringReader reader = new StringReader(data))
   {
    object obj = s.Deserialize(reader);
    return (T)obj;
   }
  }
}

Now you can simply do the following:

string input = "hello world";
string xmlData = input.ToXml();
string backFromXml = xmlData.FromXml<string>();

Thanks Steve!

3 comments:

Steve said...

I thought this was cool, but I like this better:

http://pastie.textmate.org/154909.txt

K Jacobson said...

Steve, I agree, your solution of putting the conversion from xml on the string class is a much cleaner solution. Thanks for the input! I will make that change and give you credit.

D. Patrick Caldwell said...

Hey, I enjoyed your blog post. I've been writing a lot of extension methods lately myself. Sometimes you really have to be thankful to be a C# developer, you know?

Also, I was wondering if you've tried any syntax highlighters? I use one from google code and I have a pretty easy one liner you can add to your template. If you'd like to use it, feel free.