views:

209

answers:

6

Is there a way of determining the name of a constant from a given value?

For example, given the following:

public const uint ERR_OK = 0x00000000;

How could one obtain "ERR_OK"?

I have been looking at refection but cant seem to find anything that helps me.

+2  A: 

You won't be able to do this since constants are replaced at compilation time with their literal values.

In other words the compiler takes this:

class Foo
{
    uint someField = ERR_OK;
}

and turns it into this:

class Foo
{
    uint someField = 0;
}
Andrew Hare
A: 

I don't think you can do that in a deterministic way. What if there are multiple constants with the same value?

mgroves
+3  A: 

In general, you can't. There could be any number of constants with the same value. If you know the class which declared the constant, you could look for all public static fields and see if there are any with the value 0, but that's all. Then again, that might be good enough for you - is it? If so...

public string FindConstantName<T>(Type containingType, T value)
{
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;

    foreach (FieldInfo field in containingType.GetFields
             (BindingFlags.Static | BindingFlags.Public))
    {
        if (field.FieldType == typeof(T) &&
            comparer.Equals(value, (T) field.GetValue(null)))
        {
            return field.Name; // There could be others, of course...
        }
    }
    return null; // Or throw an exception
}
Jon Skeet
Thanks Jon, this is totally along the line I was thinking...(FYI there is a missing closing parenthesis on the line that does equality check.) On testing this I get:Member 'object.Equals(object, object)' cannot be accessed with an instance reference; qualify it with a type name instead' is this a bug? It seems on the surface like this should work..
Fraser
Ah yes... I was missing a cast and a check for the field type. Fixing...
Jon Skeet
Perfect, that is exactly what I needed. Saved me having to wrap a *huge* hardware SDK that has thousands of constants with Enums (as others kindly suggested). As a bouns I all ready know the constants are unique within the class. Very nice indeed, thank you.
Fraser
+3  A: 

You may be interested in Enums instead, which can be programmatically converted from name to value and vice versa.

foson
I'm working with a 3rd party Api and have considered converting the codes to an Enumaration, it's just there are *lots*...thanks :)
Fraser
+1  A: 

I suggest you use an enum to represent your constant.

Or

string ReturnConstant(uint val)
{
     if(val == 0x00000000)
       return "ERR_OK";
     else
       return null;
}
Nick
A: 

The easiest way would be to switch to using an enum

Iain Hoult