title: What causes enum.ToString() to intern the member it represents
body: <p>I've been looking into the effects of calling <code>.ToString()</code> on enum members -- more specifically whether it creates a new string object or not.</p>
  
  <p>Consider the following enum definition:</p>
  
  <pre><code>enum MyEnum
  {
      MyValue = 0,
      MyOtherValue = 1
  }
  </code></pre>
  
  <p>If I execute the following code with breakpoints on <code>x</code>, <code>y</code> and <code>z</code> and take a heap dump at each point</p>
  
  <pre><code>static void Main(string[] args)
  {
      Console.WriteLine(typeof(MyEnum));
  
      var x = MyEnum.MyValue.ToString(); // Breakpoint 1
      var y = MyEnum.MyValue.ToString(); // Breakpoint 2
      var z = MyEnum.MyOtherValue.ToString(); // Breakpoint 3
  
      Console.WriteLine(x, y, z);
  }
  </code></pre>
  
  <p>I can see the following results:</p>
  
  <pre><code>| Stage   | # string objects |
  |---------|------------------|
  | Initial | 463              |
  | BP 1    | 465              |
  | BP 2    | 465              |
  | BP 3    | 466              |
  </code></pre>
  
  <p>I looked through <a href="https://referencesource.microsoft.com/#mscorlib/system/enum.cs,1365cfeffd45409d,references" rel="noreferrer">enum.cs</a> but couldn't find what causes the (lack of?) allocations.</p>
  
  <ol>
  <li>What causes the two allocations at the first breakpoint?</li>
  <li>Why didn't the second call cause an allocation? I don't see any lookups in the string pool and I don't expect these enum names to be interned since they are are retrieved through an invocation of a virtual method which uses reflection to find it.</li>
  <li>By manually inspecting the string values on the heap at each snapshot I can see that step 1 adds "MyValue", step 2 does not add anything and step 3 adds "MyOtherValue".</li>
  </ol>
  
  <p>The overarching question is why <code>Enum.ToString()</code> seems to intern the member it represents. What part of the code causes the interning?</p>