Thieu Nguyen
Thieu Nguyen

Reputation: 41

How to get name of variable via their value in class C#

Currently I have a class as below:

public static class JurisdictionList
{
    public const string NSW = "New South Wales";
    public const string NT = "Northern Territory";
    public const string QLD = "Queensland";
    public const string SA = "South Australia";
    public const string TAS = "Tasmania";
    public const string VIC = "Victoria";
    public const string WA = "Western Australia";
}

And I want to write a method string GetJurisdictionCode(string Jurisdiction) to return the name of each above constant respective with their value. For example GetJurisdictionCode(JurisdictionList.QLD) will return QLD.

Currently I just know to do this using Switch Case, but It looks quite long. Does any one know another ways to solve it? Thanks in advance.

Upvotes: 3

Views: 150

Answers (3)

sujith karivelil
sujith karivelil

Reputation: 29006

You can use FieldInfo and GetFields() to iterate through the fields to get property with the required value; hence The expected GetJurisdictionCode() looks like this:

 public static string GetJurisdictionCode(string Jurisdiction) 
    {
        foreach (FieldInfo p in typeof(JurisdictionList).GetFields())
        {             
            if (string.Equals(p.GetValue(p.Name),Jurisdiction))              
                return p.Name;
        }
        return "Not Found";
    }

Upvotes: 1

x2bool
x2bool

Reputation: 2906

You can't achieve what you are trying to do without doing Reflection on your code, or making it to use for example Dictionary.

Also you can change your code to use C# 6 operator "nameof" instead:

string code = nameof(JurisdictionList.QLD); // QLD

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1499770

Well you could use reflection:

public static string GetJurisdictionCode(string jurisdiction)
{
    return typeof(JurisdictionList)
        .GetTypeInfo()
        .DeclaredFields
        .Where(f => (string) f.GetValue(null) == jurisdiction)
        .FirstOrDefault()
        ?.Name;
}

But personally I'd suggest building a Dictionary<string, string> to get from code to name, and then either just using:

return codes.Where(kvp => kvp.Value == jurisdiction)
            .FirstOrDefault()
            ?.Name;

... or build up a second dictionary to go in the other direction. If you wanted the named constants as well, you could always build up both dictionaries by reflection, e.g.

public static class JurisdictionList
{
    public const string NSW = "New South Wales";
    public const string NT = "Northern Territory";
    public const string QLD = "Queensland";
    public const string SA = "South Australia";
    public const string TAS = "Tasmania";
    public const string VIC = "Victoria";
    public const string WA = "Western Australia";

    private static readonly Dictionary<string, string> CodeToName =
        typeof(JurisdictionList)
            .GetTypeInfo()
            .DeclaredFields
            .Where(f => f.FieldType == typeof(string))
            .ToDictionary(f => f.Name, f => f.GetValue(null));

    private static readonly Dictionary NameToCode =
        CodeToName.ToDictionary(kvp => kvp.Value, kvp => kvp.Key);

    // Methods using the dictionaries here
}

You should also consider having an enum, then mappings from the enum to names.

Upvotes: 7

Related Questions