James
James

Reputation: 1945

Get value of enum from list of string

I have one class called MyProduct

It is as below

public class MyProduct {
   public string Id { get; set; }

    public string CustomId { get; set; }
}

Then I created another class ListProducts

public class ListProducts
{
  public static readonly List<MyProduct > MyListOfProducts = new List<MyProduct >()
    {
       new MyProduct(){
           Id = "1",
           CustomId = ((int)MyEnum.NameOfService).ToString()
       },
        new MyProduct(){
           Id = "2",
           CustomId = ((int)MyEnum.AgeOfService).ToString()
       }
    };

 public enum MyEnum{
   NameOfService = 12,
   AgeOfService = 11
 }


}

Now i want to create a method inside class ListProducts which will return me enum string when i pass it an id.

So for example if i pass Id = 1 then it should return me enum value as "NameOfService"

I was trying something like below

public static MyEnum GetStringFromEnum(string id) => ListProducts.FirstOrDefault(x=> x.Id == Id);

But its not returning me enum value

Upvotes: 0

Views: 242

Answers (6)

Johannes
Johannes

Reputation: 6707

You can use System.Enum to get the name for you. You should check out all the methods in there - they can help a bunch with your enumeration needs.

    string GetProduct(int number)
    {
        int index = lookupIndex(number);
        return Enum.GetNames(typeof(MyEnum))[index];
    }

    private int lookupIndex(int number)
    {
        //this fits your current metadata, you could adapt the lookup here.
        return number - 1;
    }

The accepted answer deviates from my expectation. Here are additional fragments to consider:

    public MyEnum GetProduct(string name)
    {
        return (MyEnum)Enum.Parse(typeof(MyEnum), name);
    }

    public MyEnum GetProduct(int number)
    {
        return (MyEnum)number;
    }

    private int lookupIndex(int number)
    {
        Array values = Enum.GetValues(typeof(MyEnum));
        int[] intArray = (int[])values;
        return Array.FindIndex(intArray, x => x == number);
    }

Here are a few more options for related problems that may come in handy:

using System;
using System.Linq;

public enum foo
{
    unknown = 0,
    bar = 42,
    baz
}

class Program
{

    static void Main(string[] args)
    {
        Console.WriteLine($"Enum.GetName  : '{Enum.GetName(typeof(foo), 42)}'");

        var getnames = Enum.GetNames(typeof(foo));
        string names = string.Join(", ", getnames);
        Console.WriteLine($"Enum.GetNames : '{names}'");

        var getValues = Enum.GetValues(typeof(foo)); ;
        var values = string.Join(", ", from v in getValues.Cast<int>() select v.ToString());
        Console.WriteLine($"Enum.GetValues: '{values}'");

        foo caseSensitiveUnknown = (foo)Enum.Parse(typeof(foo), nameof(foo.unknown));
        Console.WriteLine($"Enum.Parse 1:   '{caseSensitiveUnknown}'");

        foo ignoreCaseUnknown = (foo)Enum.Parse(typeof(foo), "UnKnoWn", true);
        Console.WriteLine($"Enum.Parse 2:   '{ignoreCaseUnknown}'");
    }
}

I think your deeper design issue is that you have 5 identities for what seems to be the same thing. Your 5 Identities are MyEnum, CustomId, Id, (int)MyEnum, Enum.GetName(typeof(MyEnum), e). The problem is that you need to maintain all of them even in big systems. At some point you will create a database with a table for the enum and the names and integers need to be maintained on connecting libraries as well. Instead of opting for a big conversion party like this:

public class MyEnumConverter
{
    public static string ToCustomId(MyEnum e) => $"{(int)e}";
    public static string ToId(MyEnum e) => ListProducts.MyListOfProducts.First(x => x.CustomId == $"{(int)e}").Id;
    public static int ToEnumValue(MyEnum e) => (int)e;
    public static string ToEnumName(MyEnum e) => Enum.GetName(typeof(MyEnum), e);
    public static MyEnum FromCustomId(string customId) => (MyEnum)(int.Parse(customId));
    public static MyEnum FromId(string Id) => FromCustomId(ListProducts.MyListOfProducts.First(x => x.Id == Id).CustomId);
    public static MyEnum FromEnumValue(int enumValue) => (MyEnum)(enumValue);
    public static MyEnum FromEnumName(string name) => (MyEnum)Enum.Parse(typeof(MyEnum), name);
}

Consider just maintaining a single unique ID for a Product like a System.Guid that is completely detached from meaning.

Upvotes: 1

Fatikhan Gasimov
Fatikhan Gasimov

Reputation: 943

Could you try this?

  public MyEnum GetStringFromEnum(string id)
        {

            var product = MyListOfProducts.FirstOrDefault(x => x.Id.Equals(id));
            MyEnum myEnum = (MyEnum)Convert.ToInt32(product?.CustomId);
            return myEnum;

        }

For single line :

public MyEnum GetStringFromEnum(string id) =>(MyEnum) Convert.ToInt32(MyListOfProducts.FirstOrDefault(x => x.Id.Equals(id))?.CustomId);

Upvotes: 2

Apart from the answers given here to get the value, I have a concern on the design. Are those two numbers some constants or configuration values?

I strongly disagree the usage of enum in this scenario.

Upvotes: 0

Mukesh Arora
Mukesh Arora

Reputation: 1813

If you want to get the enum name from its value, you can use the Enum.GetName() method as shown below. You can pass the product id and based on that you can get the enum value and below function will give you enum name

Enum.GetName(typeof(MyEnum), 2)

Upvotes: 1

James Blackburn
James Blackburn

Reputation: 616

Your method is named 'GetStringFromEnum' yet you are passing through and ID and returning an enum. I would call it get 'GetEnumFromId' or just 'GetEnum'. Also make your CustomId property an int. You still need to cast it as (int) but no need to use .toString anymore.

public class MyProduct {
   public string Id { get; set; }

    public int CustomId { get; set; }
}
public static readonly List<MyProduct > MyListOfProducts = new List<MyProduct >()
    {
       new MyProduct(){
           Id = "1",
           CustomId = (int)MyEnum.NameOfService
       },
        new MyProduct(){
           Id = "2",
           CustomId = (int)MyEnum.AgeOfService
       }
    }

Also no need to number your enums. Below NameOfServer will = 1 and AgeOfService will = 2.

public enum MyEnum{
   NameOfService,
   AgeOfService
 }

Then you can do the following:

public static MyEnum GetEnum(string id) => ListProducts.FirstOrDefault(x=> x.CustomId == Id);

Upvotes: 1

bdn02
bdn02

Reputation: 1500

You can try to get the name for the specified integer value value and then get enum:

int integerenumvalue = 14;
string stringenum = Enum.GetName(typeof(MyEnum), integerenumvalue);
MyEnum enumvalue = (MyEnum)Enum.Parse(typeof(MyEnum), stringenum);

Upvotes: 0

Related Questions