user834850
user834850

Reputation:

Enumerating enum and cast to Name/Value

My code:

public enum WAVE_FORMAT : uint 
{
   WAVE_INVALIDFORMAT = 0x00000000, /* invalid format */
   WAVE_FORMAT_1M08 = 0x00000001,   /* 11.025 kHz, Mono,   8-bit  */
   WAVE_FORMAT_1S08 = 0x00000002    /* 11.025 kHz, Stereo, 8-bit  */
}

public SayIfSupported(uint myFormat):-
            foreach(uint format in Enum.GetValues(typeof(WAVE_FORMAT))){
                if ((myFormat & format) == format) {
                   Say("Supported: " + ((WAVE_FORMAT)format).ToString());
                   }
                }

What is the actual JIT code will do in here : ((WAVE_FORMAT)format).ToString()?

Shall it enumerate again, when trying to cast to appropriate enum value?

How to avoid the extra enumeration elegantly?

Upvotes: 0

Views: 89

Answers (1)

Matthew Watson
Matthew Watson

Reputation: 109567

It's not the JITTer that does this. It's the code for Enum.ToString()

You can look at the ReferenceSource to discover the implementation of Enum.ToString().

Ultimately it ends up calling this code if the [Flags] attribute is not applied to the enum. (It's not in your example, but perhaps it should be!)

public virtual string GetEnumName(object value)
{
    if (value == null)
        throw new ArgumentNullException("value");

    if (!IsEnum)
        throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
    Contract.EndContractBlock();

    Type valueType = value.GetType();

    if (!(valueType.IsEnum || Type.IsIntegerType(valueType)))
        throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");

    Array values = GetEnumRawConstantValues();
    int index = BinarySearch(values, value);

    if (index >= 0)
    {
        string[] names = GetEnumNames();
        return names[index];
    }

    return null;
}

Note how it does a binary search and uses reflection to get at the enum names. This is not very efficient, but it's better than looping through all the enum values.

If you're worried about the speed, you could use a simple switch, or a dictionary to look up the strings, or just a simple array if the enum values are contiguous.

Upvotes: 1

Related Questions