1

Consider the following

public enum E
{
  A = 1,
  B = 1  
}

public string F(E input)
{
 return input.ToString();
}

F(E.B); //returns "A"

Now I know that you're not supposed to do ((E)1).ToString(), as it could resolve to A or B (http://msdn.microsoft.com/en-us/library/16c1xs4z.aspx).
But when it's an explicitly chosen value (e.g. B), why does ToString() behave wierdly (returning A)?

When debugging its possible to see that input is B, is it possible to get the selected field in code?

EDIT
This question relates to how the debugger knows which value is passed to F(), whilst in code it doesn't seem possible to detect this?

10
  • enum members is actualy numbers, named constants, so it works correctly Commented Aug 7, 2012 at 18:12
  • 1
    You would expect that F(E.B) would return "B" not "A" Commented Aug 7, 2012 at 18:14
  • I understand that enums are names for underlying values. What im trying to figure out is when an enum has 2+ names for the same underlying value the behaviour is different to expected Commented Aug 7, 2012 at 18:16
  • When you write E.B fraemwork translate it to the concreate number in your example it is 1. And when it will try to parse/resolve it will look in the enum definitaion to try to find named member for this number and it will select first item. Enum is not a reference type. Commented Aug 7, 2012 at 18:16
  • 1
    In the reference that you gave, it read :"The following method call attempts to retrieve the name of a member of the Shade enumeration whose underlying value is 1. The method can return either "Gray" or "Grey", and your boldcode should not make any assumptions about which string will be returnedbold." Commented Aug 7, 2012 at 18:20

2 Answers 2

2

The enum is really just an integer value. What happens is that, when you call input.ToString(), the enum does the following:

  • Get the value of input, in this case, 1
  • Passes this to an internal formatting routine, which finds the matching name (if this isn't decorated with [Flags])
  • Returns the name

When it goes to find the matching name, it finds the first match with a value of 1, in this case, E.A, and prints "A".

Normally, this isn't a problem, as you would typically only have one enum value per name.

When debugging its possible to see that input is B, is it possible to get the selected field in code?

The problem is that input is not "B" - the input is a value of 1 wrapped in an E variable, which means that input is E.A and E.B.

To demonstrate, run:

using System;
class Program
{
    public enum E
    {
        A = 1,
        B = 1
    }

    static void Main(string[] args)
    {
        E value = E.B;


        Console.WriteLine(value == E.B);
        Console.WriteLine(value == E.A);

        Console.ReadKey();
    }

}

This will print True twice, as value is both E.A and E.B.

If you break on Console.ReadKey, the debugger will show value as "A", as well.

Sign up to request clarification or add additional context in comments.

4 Comments

I'm not sure it always finds the "first" match. And if it does, is it first wrt. the textual order of the source code, or first wrt. the numerical value? The doc says: If multiple enumeration members have the same underlying value and you attempt to retrieve the string representation of an enumeration member's name based on its underlying value, your code should not make any assumptions about which name the method will return.
@JeppeStigNielsen Which is absolutely true - you shouldn't make any assumptions about it. The current implementation does happen to put it in textual order, so with the MS stack, it finds the first value, though. It's just not guaranteed by spec.
Yes you're exactly right, but in your example, if you break after E value = E.B the debugger shows that value is B not A/both/unknown
Apologies, I cannot seem to reproduce the problem at the moment.
0

The problem ist that the two possible enum values A and B both have an integer value of 1, making it impossible to make the distinction between A and B since C# just passes a value of 1 as argument to the method.

5 Comments

Ok, i understand that c# will pass 1 in the method call, but how does the debugger know which enum name this came from, i.e. B
@SimonLaing The debugger doesn't know that.
When breaking in F(E.B) its possible to see the value of input, which will be shown as B
Let me try to reproduce the problem, i wrote the question from a rough copy of the issue i experienced earlier today
Apologies, I cannot seem to reproduce the problem at the moment. My debugger also shows E.A

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.