title: Iterate over Enum elements (Not just names and not just values)
body: <p>I have an enumeration of enum elements and description attributes</p>
  
  <pre class="lang-cs prettyprint-override"><code>    public enum CourseGrades
      {
          [Description("A")]
          A = 11,
          [Description("A-")]
          AMinus = 10,
          [Description("B+")]
          BPlus = 9,
          [Description("B")]
          B = 8,
          [Description("B-")]
          BMinus = 7,
          [Description("C+")]
          CPlus = 6,
          [Description("C")]
          C = 5,
          [Description("C-")]
          CMinus = 4,
          [Description("D+")]
          DPlus = 3,
          [Description("D")]
          D = 2,
          [Description("D-")]
          DMinus = 1,
          [Description("E")]
          E = 0,
          [Description("Audit")]
          AU = -1,
          [Description("Incomplete")]
          IC = -2,
          [Description("Withdrawl")]
          WD = -3,
          [Description("Not Applicable")]
          NA = -4
      }
  </code></pre>
  
  <p>My issue is that I am trying to build a list of the descriptions and I am getting stuck on how to do that. All of the answers I have seen say to use <code>Enum.GetNames()</code> or <code>Enum.GetValues()</code> which I know how to do.</p>
  
  <p>The issue with both of those is that they return a string array which has lost all context on where it came from so that I am not able to follow it to get the description for the particular enum value that I want.</p>
  
  <p>The way I get the description right now is to call <code>CourseGrades.A.GetDescription()</code> because I have an extension method that handles getting the description attribute <a href="https://pastebin.com/cHzx6su9" rel="nofollow noreferrer">view code</a>.</p>
  
  <p>I've been hoping to do something like</p>
  
  <pre class="lang-cs prettyprint-override"><code>var elements = System.Enum.GetElements(CourseGrades);
  var dict = new Dictionary&lt;CourseGrades, string&gt;();
  
  foreach (var element in elements) {
      dict.Add(element, element.GetDescription());
  }
  </code></pre>
  
  <p>but I am beginning to think that something like this isn't possible to do.</p>
  
  <p>I have been trying hard to avoid brute forcing it by doing </p>
  
  <pre class="lang-cs prettyprint-override"><code>private Dictionary&lt;CourseGrades, string&gt; _courseGradesWithCaption = null;
  public Dictionary &lt; CourseGrades, string &gt; CourseGradesWithCaptions
  {
      get
      {
          if ( _courseGradesWithCaption == null )
              _courseGradesWithCaption = new Dictionary &lt; CourseGrades, string &gt; ()
              {
                  { CourseGrades.A, CourseGrades.A.GetDescription () }
                  , { CourseGrades.AMinus, CourseGrades.AMinus.GetDescription () }
                  , { CourseGrades.BPlus, CourseGrades.BPlus.GetDescription () }
                  // ... snip ...
              };
          return _courseGradesWithCaption;
      }
  }
  </code></pre>
  
  <p>I thought I was getting somewhere by borrowing how the extension method linked above went through the enumeration by doing</p>
  
  <pre class="lang-cs prettyprint-override"><code>public static class EnumerationCaptionsBuilder
  {
      public static Dictionary &lt; T, string &gt; BuildCaptions&lt;T&gt; ( T e ) where T : IConvertible
      {
          if (!(e is System.Enum)) throw new ArgumentException("e is expected to be an enumeration.");
  
          var type = e.GetType ();
          var values = System.Enum.GetValues ( type );
          var dict = new Dictionary&lt;T, string&gt; ();
  
  
          foreach ( var val in values )
          {
              if ( (int) val != e.ToInt32 ( CultureInfo.InvariantCulture ) ) continue;
  
              var enumElement = type.GetMember ( type.GetEnumName ( val ) ?? throw new InvalidOperationException ());
  
              dict.Add(enumElement, enumElement.GetDescription());
          }
      }
  }
  </code></pre>
  
  <p>But that was when I learned that <code>type.GetMember</code> returns a MemberInfo object which is not what I am looking for.</p>
  
  <p>Is there a way to do what I am wanting to do or am I just barking up an impossible tree?</p>