5

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.

Fraser
  • 15,275
  • 8
  • 53
  • 104

7 Answers7

15

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
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 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 Jun 30 '09 at 15:51
  • 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 Jun 30 '09 at 23:57
4

I may be late.. but i think following could be the answer

public static class Names
    {
        public const string name1 = "Name 01";
        public const string name2 = "Name 02";

        public static string GetName(string code)
        {
            foreach (var field in typeof(Names).GetFields())
            {
                if ((string)field.GetValue(null) == code)
                    return field.Name.ToString();
            }
            return "";
        }
    }

and following will print "name1"

string result = Names.GetName("Name 01");
Console.WriteLine(result )
Yohan
  • 379
  • 1
  • 5
  • 14
3

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

foson
  • 10,037
  • 2
  • 35
  • 53
  • 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 Jun 30 '09 at 15:28
  • Enums allow you to very conveniently do this: string s = Enum.GetName(typeof(MyType), MyValue); BUT! enums are also actually constants under the hood, and it is legal to have multiple enums with differing names but with the same value, just as with constants. So unless your enums are in fact uniquely valued, this won't always do what you hope. – MickeyfAgain_BeforeExitOfSO Sep 17 '19 at 17:50
2

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
  • 344,730
  • 71
  • 640
  • 635
0

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

Matthew Groves
  • 25,181
  • 9
  • 71
  • 121
0

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
  • 3,217
  • 5
  • 30
  • 42
0

The easiest way would be to switch to using an enum

Iain Hoult
  • 3,889
  • 5
  • 25
  • 39