Phil Langeberg
Phil Langeberg

Reputation: 117

look up constants based on value

I have a 3rd party struct that is comprised of the following:

[StructLayout(LayoutKind.Sequential, Size=1)]
public struct BigBlueReasonCodes
{
    public const int ABC_REASONCODE_DESCRIPTION001 = 1000;
    public const int ABC_REASONCODE_DESCRIPTION002 = 1005;
    public const int ABC_REASONCODE_DESCRIPTION003 = 1010;
    public const int DEF_REASONCODE_DESCRIPTION004 = 2001;
    public const int DEF_REASONCODE_DESCRIPTION005 = 2010;
    public const int DEF_REASONCODE_DESCRIPTION006 = 2013;
    public const int GHI_REASONCODE_DESCRIPTION007 = 3050;
    public const int GHI_REASONCODE_DESCRIPTION008 = 3050;
    public const int GHI_REASONCODE_DESCRIPTION009 = 3052;
    public const string JKL_REASONCODE_DESCRIPTION010 = "XYZ";
    public const string GHI_REASONCODE_DESCRIPTION011 = "ST";


  static BigblueReasonCodes();
}

I am trying to look up the reason description(the field name) based on the reason code(the value) so my class can do someting like:

string failureReason = GetReasonDescription(reasoncode);

Somethings of mention are some have int values and some have string values. I am only worried about the ones with int values. I also only want the ones that start with GHI_ if possible but not a big deal.

Upvotes: 1

Views: 123

Answers (3)

Elisha
Elisha

Reputation: 23780

You can solve it using reflection, by analyzing the struct:

public string GetReasonDescription(int reasonCode)
{
    return
        typeof(BigBlueReasonCodes)
            .GetFields(BindingFlags.Public | BindingFlags.Static)
            .Where(field => field.FieldType == typeof(int)) // Filter int values
            .Where(field => field.Name.StartsWith("GHI"))
            .Where(field => (int) field.GetValue(null) == reasonCode)
            .Select(field => field.Name).First(); // Assuming a field must exists
}

Usage example:

[Test]
public void GetReasonDescriptionTest()
{
    string reasonDescription = GetReasonDescription(3050);
    Assert.That(reasonDescription, Is.EqualTo("GHI_REASONCODE_DESCRIPTION007"));
}

Upvotes: 6

Thomas
Thomas

Reputation: 64645

If you stuffed the integer values into enum instead of constants, you could do

public enum BigBlueReasonCode
{
    ABC_REASONCODE_DESCRIPTION01 = 1000,
    ABC_REASONCODE_DESCRIPTION01 = 1005,
    ABC_REASONCODE_DESCRIPTION01 = 1010,
    DEF_REASONCODE_DESCRIPTION01 = 2001,
    DEF_REASONCODE_DESCRIPTION01 = 2010,
    DEF_REASONCODE_DESCRIPTION01 = 2013,
    GHI_REASONCODE_DESCRIPTION01 = 3050,
    GHI_REASONCODE_DESCRIPTION01 = 3051,
    GHI_REASONCODE_DESCRIPTION01 = 3052
}

var failureCode = Enum.GetName( reasoncode )

(Granted, as is this code will not work as is because you have duplicates in the names but it wouldn't compile as constants either.)

Upvotes: 1

Oded
Oded

Reputation: 499072

Looks like your integer consts should really be an enumeration (or several enumerations) - this will also allow conversion to and from integers.

You could do this via reflection, but it will be slower than converting to enums.

Upvotes: 4

Related Questions