What causes enum.ToString() to intern the member it represents

456 Views Asked by At

I've been looking into the effects of calling .ToString() on enum members -- more specifically whether it creates a new string object or not.

Consider the following enum definition:

enum MyEnum
{
    MyValue = 0,
    MyOtherValue = 1
}

If I execute the following code with breakpoints on x, y and z and take a heap dump at each point

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);
}

I can see the following results:

| Stage   | # string objects |
|---------|------------------|
| Initial | 463              |
| BP 1    | 465              |
| BP 2    | 465              |
| BP 3    | 466              |

I looked through enum.cs but couldn't find what causes the (lack of?) allocations.

  1. What causes the two allocations at the first breakpoint?
  2. 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.
  3. 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".

The overarching question is why Enum.ToString() seems to intern the member it represents. What part of the code causes the interning?

0

There are 0 best solutions below