title: How would you refactor a "switch on Type" to be polymorphic if you don't control the types involved?
body: <p>I'm writing a <a href="http://microformats.org" rel="nofollow noreferrer">microformats</a> parser in C# and am looking for some refactoring advice. This is probably the first "real" project I've attempted in C# for some time (I program almost exclusively in VB6 at my day job), so I have the feeling this question may become the first in a series ;-)</p>
  
  <p>Let me provide some background about what I have so far, so that my question will (hopefully) make sense.</p>
  
  <p>Right now, I have a single class, <code>MicroformatsParser</code>, doing all the work. It has an overloaded constructor that lets you pass a <code>System.Uri</code> or a <code>string</code> containing a URI: upon construction, it downloads the HTML document at the given URI and loads it into an <code>HtmlAgilityPack.HtmlDocument</code> for easy manipulation by the class.</p>
  
  <p>The basic API works like this (or will, once I finish the code...):</p>
  
  <pre><code>MicroformatsParser mp = new MicroformatsParser("http://microformats.org");
  List&lt;HCard&gt; hcards = mp.GetAll&lt;HCard&gt;();
  
  foreach(HCard hcard in hcards) 
  {
      Console.WriteLine("Full Name: {0}", hcard.FullName);
  
      foreach(string email in hcard.EmailAddresses)
          Console.WriteLine("E-Mail Address: {0}", email);
  }
  </code></pre>
  
  <p>The use of generics here is intentional. I got my inspiration from the way that the the Microformats library in Firefox 3 works (and the Ruby <code>mofo</code> gem). The idea here is that the parser does the heavy lifting (finding the actual microformat content in the HTML), and the microformat classes themselves (<code>HCard</code> in the above example) basically provide the schema that tells the parser how to handle the data it finds.</p>
  
  <p>The code for the <code>HCard</code> class should make this clearer (note this is a not a complete implementation):</p>
  
  <pre><code>[ContainerName("vcard")]
  public class HCard
  {
      [PropertyName("fn")]
      public string FullName;
  
      [PropertyName("email")]
      public List&lt;string&gt; EmailAddresses;
  
      [PropertyName("adr")]
      public List&lt;Address&gt; Addresses;
  
      public HCard()
      { 
      }
  }
  </code></pre>
  
  <p>The attributes here are used by the parser to determine how to populate an instance of the class with data from an HTML document. The parser does the following when you call <code>GetAll&lt;T&gt;()</code>:</p>
  
  <ul>
  <li>Checks that the type <code>T</code> has a <code>ContainerName</code> attribute (and it's not blank)</li>
  <li>Searches the HTML document for all nodes with a <code>class</code> attribute that matches the <code>ContainerName</code>. Call these the "container nodes".</li>
  <li>For each container node:
  
  <ul>
  <li>Uses reflection to create an object of type <code>T</code>.</li>
  <li>Get the public fields (a <code>MemberInfo[]</code>) for type <code>T</code> via reflection</li>
  <li>For each field's <code>MemberInfo</code>
  
  <ul>
  <li>If the field has a <code>PropertyName</code> attribute
  
  <ul>
  <li>Get the value of the corresponding microformat property from the HTML</li>
  <li><strong>Inject the value found in the HTML into the field (i.e. set the value of the field on the object of type <code>T</code> created in the first step)</strong></li>
  <li>Add the object of type <code>T</code> to a <code>List&lt;T&gt;</code></li>
  </ul></li>
  </ul></li>
  <li>Return the <code>List&lt;T&gt;</code>, which now contains a bunch of microformat objects</li>
  </ul></li>
  </ul>
  
  <p>I'm trying to figure out a better way to implement the step in <strong>bold</strong>. The problem is that the <code>Type</code> of a given field in the microformat class determines not only what node to look for in the HTML, but also how to interpret the data.</p>
  
  <p>For example, going back to the <code>HCard</code> class I defined above, the <code>"email"</code> property is bound to the <code>EmailAddresses</code> field, which is a <code>List&lt;string&gt;</code>. After the parser finds all the <code>"email"</code> child nodes of the parent <code>"vcard"</code> node in the HTML, it has to put them in a <code>List&lt;string&gt;</code>. </p>
  
  <p>What's more, if I want my <code>HCard</code> to be able to return phone number information, I would probably want to be able to declare a new field of type <code>List&lt;HCard.TelephoneNumber&gt;</code> (which would have its own <code>ContainerName("tel")</code> attribute) to hold that information, because there can be multiple <code>"tel"</code> elements in the HTML, and the <code>"tel"</code> format has its own sub-properties. But now the parser needs to know how to put the telephone data into a <code>List&lt;HCard.TelephoneNumber&gt;</code>.</p>
  
  <p>The same problem applies to <code>Float</code>S, <code>DateTime</code>S, <code>List&lt;Float&gt;</code>S, <code>List&lt;Integer&gt;</code>S, etc.</p>
  
  <p>The obvious answer is to have the parser switch on the type of field, and do the appropriate conversions for each case, but I want to avoid a giant <code>switch</code> statement. Note that I'm not planning to make the parser support every possible <code>Type</code> in existence, but I will want it to handle most scalar types, and the <code>List&lt;T&gt;</code> versions of them, along with the ability to recognize other microformat classes (so that a microformat class can be composed from other microformat classes).</p>
  
  <p>Any advice on how best to handle this? </p>
  
  <p>Since the parser has to handle primitive data types, I don't think I can add polymorphism at the type level... </p>
  
  <p>My first thought was to use method overloading, so I would have a series of a <code>GetPropValue</code> overloads like <code>GetPropValue(HtmlNode node, ref string retrievedValue)</code>, <code>GetPropValue(HtmlNode, ref List&lt;Float&gt; retrievedValue)</code>, etc. but I'm wondering if there is a better approach to this problem.</p>