1

I have a class that contains a bunch of const strings similar to this

public class ReportStrings
{
    public const string ReportOne = "REPORTNAME_ONE";
    public const string ReportTwo = "REPORTNAME_TWO";
    public const string ReportThree = "REPORTNAME_THREE"; 
}

I have an enum that I'm creating to eventually replace the use of these strings through out my apps code that is similar to this below.

Public enum ReportIDs
{
    ReportOne = 10001
    ReportTwo = 10002
    ReportThree = 10003
}

I'm wondering if there is a way to map the two so that if one of the const strings is used in a method it knows how to map that string to the enum value for use else where. An example use case being if a method currently takes in a List<string> containing strings that match to whats in ReportStrings but will eventually move to a List<ReportIDs> how can I set up the method to support using either one or the other?

Stavros_S
  • 2,145
  • 7
  • 31
  • 75
  • 4
    Lookup the `[DescriptionAttribute()]` in `C#`. Or create a static dictionary with the IDs and names. – John Alexiou Mar 18 '15 at 19:39
  • why don't you use a dictionary or a new class that is privately constructed? – Daniel A. White Mar 18 '15 at 19:42
  • I was looking at doing something similar to what is shown in this answer http://stackoverflow.com/questions/1187085/string-to-enum-conversion-in-c-sharp But I'm not sure how I can use this in a situation where I do something like `if (item.ReportStrings[n] != ReportStrings. ReportTwo)` – Stavros_S Mar 18 '15 at 19:48

3 Answers3

2

You can add the description attribute

public enum ReportIDs
{
    [Description("REPORTNAME_ONE")]
    ReportOne = 10001,

    [Description("REPORTNAME_TWO")]
    ReportTwo = 10002,

    [Description("REPORTNAME_THREE")]
    ReportThree = 10003,
}

To get the enum description value have a look at this link How to get C# Enum description from value?

and to get a enum from the description have a look at this link Get Enum from Description attribute

Community
  • 1
  • 1
Trekco
  • 1,246
  • 6
  • 17
2

Are you open to the idea of giving your enum values the same names as the old strings? You could then have an overload for each method that takes one of the enums that takes a string instead, and convert it before calling the enum version:

public enum ReportIDs
{
    REPORTNAME_ONE = 10001,
    REPORTNAME_TWO = 10002,
    REPORTNAME_THREE = 10003
}

private void test()
{
    SomeMethod(ReportIDs.REPORTNAME_ONE);
    //or
    SomeMethod(ReportStrings.ReportOne);
}

private void SomeMethod(string report)
{
    SomeMethod((ReportIDs) Enum.Parse(typeof(ReportIDs), report));
}

private void SomeMethod(ReportIDs report)
{
    //logic that uses new enum
}
James Thorpe
  • 31,411
  • 5
  • 72
  • 93
  • in my case the method that uses the enum/strings just take in a custom type object. A part of the method then acts on a param containing the list. I guess I could split that section out into a private method and create overloads for it as a way of handling this. – Stavros_S Mar 18 '15 at 20:00
  • This technique would also work with the `Description` attribute version mentioned in the comments and other answer, and is probably cleaner in the long run, you just swap out the logic for finding the enum value instead of using `Enum.Parse` – James Thorpe Mar 18 '15 at 20:00
1

Here is complete solution with the [DescriptionAttribute]

public enum ReportIDs
{
    [Description("REPORTNAME_ONE")]
    ReportOne=10001,
    [Description("REPORTNAME_TWO")]
    ReportTwo=10002,
    [Description("REPORTNAME_THREE")]
    ReportThree=10003,
}

static class Program
{
    static void Main(string[] args)
    {
        // Make list of names
        var reports=new List<string>(new string[] { "REPORTNAME_ONE", "REPORTNAME_THREE" });
        // Get a list of enum values
        var ids=reports.Select((rpt) => rpt.GetEnumFromDescription<ReportIDs>()).ToList();
    }

    /// <summary>
    /// Retrieve the description on the enum, e.g.
    /// [Description("Bright Pink")]
    /// BrightPink = 2,
    /// Then when you pass in the enum, it will retrieve the description
    /// </summary>
    /// <param name="en">The Enumeration</param>
    /// <returns>A string representing the friendly name</returns>
    public static string GetDescriptionFromEnum(this Enum en)
    {
        Type type=en.GetType();
        MemberInfo[] memInfo=type.GetMember(en.ToString());
        if(memInfo!=null&&memInfo.Length>0)
        {
            object[] attrs=memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

            if(attrs!=null&&attrs.Length>0)
            {
                return ((DescriptionAttribute)attrs[0]).Description;
            }
        }

        return en.ToString();
    }

    /// <summary>
    /// Retrieve the enum value of type T with specified description
    /// </summary>
    /// <typeparam name="T">The enum type to look into</typeparam>
    /// <param name="description">The description to look for</param>
    /// <returns>Either the enum value, or default(T)</returns>
    public static T GetEnumFromDescription<T>(this string description)
        where T: struct, IComparable
    {
        Type type=typeof(T);
        T[] members=type.GetEnumValues().Cast<T>().ToArray();
        for(int i=0; i<members.Length; i++)
        {
            var descr=GetDescriptionFromEnum(members[i] as Enum);
            if(description.Equals(descr))
            {
                return members[i];
            }
        }
        return default(T);
    }
}
John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • What if the ReportStrings are being passed into a method as a list and then being enumerated? I would I need run GetEnumFromDescription before and pass in each individual string inside of a loop? – Stavros_S Mar 18 '15 at 20:12
  • 1
    Στάυρο use LINQ like the example above `reports.Select((rpt) => rpt.GetEnumFromDescription()).ToList()` to convert between lists. You can use the `.Select()` statement inside a method to convert to a list of ids. – John Alexiou Mar 18 '15 at 20:27
  • Efxaristo poli! ;) eiste Ellinas? I'm not too familiar with using LINQ I will have to play around with it. – Stavros_S Mar 18 '15 at 20:48
  • Πατρίδα για χαρα σου. LINQ operates on `IEnumerable` classes and the select statement transforms from one collection to another based the method you specify (in this case `GetEnumFromDescriton()`). – John Alexiou Mar 18 '15 at 23:55