title: Representing heirarchical enumeration
body: <p>I have a set of enumeration values (fault codes to be precise). The code is a 16 bit unsigned integer. I am looking for a data structure that could represent such an enumeration. A similar question has been asked here: <a href="https://stackoverflow.com/questions/3975515/whats-the-best-c-pattern-for-implementing-a-hierarchy-with-an-enum">What's the best C# pattern for implementing a hierarchy with an enum?</a>. But this hierarchy is deeper.</p>
  
  <p><br><b>Sample enumeration values</b><br></p>
  
  <pre><code>Current = 0x2000,
  Current_DeviceInputSide = 0x2100,
  ShortToEarth = 0x2120,
  ShortToEarthInPhase1 = 0x2121,
  ShortToEarthInPhase2 = 0x2122,
  ShortToEarthInPhase3 = 0x2123
  </code></pre>
  
  <p><br><b>Use case</b><br>
  When the user provides a code then the UI has to display the equivalent meaning of the code with the hierarchy. 
  <br>
  For example, if the user provides a value <code>0x2121</code> then the UI has to display <code>Short to earth in phase 1 in the current at device input side</code>. The best way to represent this is by using a hierarchical notation: <code>Current : DeviceInputSide : ShortToEarth : ShortToEarthInPhase1</code>.</p>
  
  <p><br><b>Competing approaches</b><br>
  I have three competing approaches to represent the enumeration:</p>
  
  <ol>
  <li>Create an enumeration at each level of the hierarchy. Then use a controller class to resolve the name.</li>
  <li>Store the enumeration values in an xml and use LINQ to generate the meaning of the code.</li>
  <li>Store the enumeration values in an xml. During the application startup. Create a singleton instance to retrieve the meaning. The instance contains a dictionary populated with the values from the xml. </li>
  </ol>
  
  <p><br>
  <b>Approach 1</b><br>
  The enumerations:</p>
  
  <pre><code>enum WarnCodes
  {
      None= 0x000,
      Current = 0x2000
  }
  
  enum WarnCodes_Current
  {
      DeviceInputSide = 0x2100,
      DeviceOutputSide = 0x2200
  }
  
  enum WarnCodes_Current_DeviceInputSide
  {
      ShortToEarth = 0x2120,
      ShortCircuit = 0x2130
  }
  
  enum WarnCodes_Current_DeviceInputSide_ShortToEarth 
  {
      InPhase1 = 0x2121,
      InPhase2 = 0x2122
  }
  </code></pre>
  
  <p>The controller:</p>
  
  <pre><code>public string GetMeaning(int code)
  {
      int bitMask = 0xF000;
      int maskedCode = bitMask & code;
      StringBuilder meaning = new StringBuilder();
  
      switch (maskedCode)
      {
          case WarnCodes.Current:
              meaning.Append("Current : ");
              bitMask = 0xFF00;
              maskedCode = bitMask & code;
              switch (maskedCode)
              {
                  case WarnCodes_Current.DeviceInputSide:
                      meaning.Append("Current : Device Input Side :");
                      ...
                      break;
              }
  
              break;
  
              ...
      }
  }
  </code></pre>
  
  <p><br>
  <b>Approach 2</b><br>
  The xml to store the enumeration values looks like this
  <pre><code>&lt;WarnCodes>
    &lt;code hex="2000" meaning="Current">
      &lt;code hex="2100" meaning="Current, Device Input side">
        &lt;code hex="2120" meaning="Short to Earth">
          &lt;code hex="2121" meaning="Short to earth in Phase L1"/>
          &lt;code hex="2122" meaning="Short to earth in Phase L2"/>
        &lt;/code>
      &lt;/code>
    &lt;/code>
  &lt;/WarnCodes>
  </pre></code>
  And the method used to query the codes is:</p>
  
  <pre><code>XElement rootElement = XElement.Load(settingsFilePath);
  public string GetHierarchicalMeaning(int code)
  {
      XElement rootElement = XElement.Load(warnCodesFilePath);
  
      List&lt;string> meanings = new List();
      StringBuilder stringBuilder = new StringBuilder();
      IEnumerable&lt;XElement> elements;
  
      elements = from el in rootElement.Descendants("code")
                 where (string)el.Attribute("hex") == code.ToString("X")
                 select el;
  
      XElement element = elements.First();
  
      while (element.Parent != null)
      {
          meanings.Add(element.Attribute("meaning").Value);
          element = element.Parent;
      }
  
      meanings.Reverse();
  
      foreach (string meaning in meanings)
      {
          stringBuilder.AppendFormat("{0} : ", meaning);
      }
  
      return stringBuilder.ToString().Trim().TrimEnd(':').Trim();
  }
  </code></pre>
  
  <p><br>
  <b>Approach 3</b><br>
  The xml to store the enumeration values is same as in <b>Approach 2</b>. The dictionary is populated from the <code>xml</code> by <code>GetChildren()</code>. </p>
  
  <pre><code>private Dictionary&lt;int, WarnCodeValue> warnCodesDictionary;
  
  public void Initialize()
  {
      XElement rootElement = XElement.Load(settingsFilePath);
      warnCodesDictionary = GetChildren(rootElement);
  }
  
  private Dictionary&lt;int, WarnCodeValue> GetChildren(XElement element)
  {
      if (element.Descendants().Count() > 0)
      {
          Dictionary&lt;int, WarnCodeValue> childNodeDictionary = new Dictionary();
  
          foreach (XElement childElement in element.Elements())
          {
              int hex = Convert.ToInt32(childElement.Attribute("hex").Value, 16);
              string meaning = childElement.Attribute("meaning").Value;
  
              Dictionary&lt;int, WarnCodeValue> dictionary = GetChildren(childElement);
              WarnCodeValue warnCodeValue;
              if (dictionary == null)
              {
                  warnCodeValue = new WarnCodeValue() {Meaning = meaning};
              }
              else
              {
                  warnCodeValue = new WarnCodeValue() {Meaning = meaning, ChildNodes = dictionary};
              }
  
              childNodeDictionary.Add(hex, warnCodeValue);
          }
  
          return childNodeDictionary;
      }
  
      return null;
  }
  </code></pre>
  
  <p>The meanings are retrieved using <code>GetHierarchicalMeaning()</code>:</p>
  
  <pre><code>public string GetHierarchicalMeaning(int code)
  {
      StringBuilder stringBuilder = new StringBuilder();
  
      int firstLevel = code & 0xF000;
      int secondLevel = code & 0xFF00;
      int thirdLevel = code & 0xFFF0;
  
      if(warnCodesDictionary.ContainsKey(firstLevel))
      {
          stringBuilder.AppendFormat("{0} : ", warnCodesDictionary[firstLevel].Meaning);
          if (warnCodesDictionary[firstLevel].ChildNodes != null && 
              warnCodesDictionary[firstLevel].ChildNodes.ContainsKey(secondLevel))
          {
              stringBuilder.AppendFormat("{0} : ", warnCodesDictionary[firstLevel].ChildNodes[secondLevel].Meaning);
  
              if (warnCodesDictionary[firstLevel].ChildNodes[secondLevel].ChildNodes != null &&
                  warnCodesDictionary[firstLevel].ChildNodes[secondLevel].ChildNodes.ContainsKey(thirdLevel))
              {
                  stringBuilder.AppendFormat("{0} : ", 
                      warnCodesDictionary[firstLevel].ChildNodes[secondLevel].ChildNodes[thirdLevel].Meaning);
  
                  if (warnCodesDictionary[firstLevel].ChildNodes[secondLevel].ChildNodes[thirdLevel].ChildNodes != null &&
                      warnCodesDictionary[firstLevel].ChildNodes[secondLevel].ChildNodes[thirdLevel].ChildNodes.ContainsKey(code))
                  {
                      stringBuilder.AppendFormat("{0} : ", 
                          warnCodesDictionary[firstLevel].ChildNodes[secondLevel].ChildNodes[thirdLevel].ChildNodes[code].Meaning);
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>The <code>WarnCodeValue</code> class:</p>
  
  <pre><code>class WarnCodeValue
  {
      public string Meaning
      { get; set; }
  
      public Dictionary&lt;int, WarnCodeValue> ChildNodes { get; set; }
  }
  </code></pre>
  
  <p><br>
  <b>Questions</b><br></p>
  
  <ol>
  <li>Which of the above 3 approaches is better from a performance point of view? </li>
  <li>Are there any other approaches for representing the enumeration?</li>
  <li>Any improvements to the code?</li>
  </ol>