3

So I have an enum:

public enum myEnum
{
    IBM = 1,
    HP = 2,
    Lenovo = 3
}

I have a Brand class

public class Brand
{
    public Brand(string name, int id)
    {
        Name = name;
        Id = id;
    }

    public string Name { get; private set; }
    public int Id { get; private set; }
}

I want to create a List of Brand objects populated with the data from the MyEnum. Something like:

private IEnumerable<Brand> brands = new List<Brand>
{
    new Brand(myEnum.IBM.ToString(), (int) myEnum.IBM),
    new Brand(myEnum.HP.ToString(), (int) myEnum.HP),
    new Brand(myEnum.Lenovo.ToString(), (int) myEnum.Lenovo),
};

I can create two arrays - one with enum names and the other with enum ids and foreach them to create Brand object for every iteration but wonder if there is a better solution.

Finally, I am going with Royi Mindel solution as according to me it is the most appropriate . Many thanks to Daniel Hilgarth for his answer and his help making Royi Mindel suggestion work. I would give credit to both of them for this question if I could.

public static class EnumHelper
{
    public static IEnumerable<ValueName> GetItems<TEnum>() 
        where TEnum : struct, IConvertible, IComparable, IFormattable
    {
        if (!typeof(TEnum).IsEnum)
            throw new ArgumentException("TEnum must be an Enumeration type");

        var res = from e in Enum.GetValues(typeof(TEnum)).Cast<TEnum>()
                  select new ValueName() { Id = Convert.ToInt32(e), Name = e.ToString() };

        return res;
    }
}

public struct ValueName
{
    public int Id { get; set; }
    public string Name { get; set; }
}
11
  • I think It's a best solutions !!! Commented Oct 7, 2013 at 8:36
  • Take a look at Enum.GetNames(). Commented Oct 7, 2013 at 8:37
  • 3
    keep only MyEnum in Brand class, and create a property that return enum.ToString() if required Commented Oct 7, 2013 at 8:37
  • 1
    This might help Commented Oct 7, 2013 at 8:38
  • 1
    @MaxMommersteeg: BTW: StyleCop does highlight the semicolon as a problem: "The code contains an extra semicolon. [StyleCop Rule: SA1106]" Commented Oct 7, 2013 at 8:53

3 Answers 3

13
var brands = Enum.GetValues(typeof(myEnum))
                 .Cast<myEnum>()
                 .Select(x => new Brand(x.ToString(), (int)x))
                 .ToArray();
Sign up to request clarification or add additional context in comments.

1 Comment

The downvoter is encouraged to leave a comment, so I can fix what ever you think is incorrect. Hint: I tested this code and it works.
3

I would suggest making a general ValueName class to fit all enums and not make specific classes to fit specific enums

public static class EnumHelper
{
    public static IEnumerable<ValueName> GetItems<TEnum>() 
        where TEnum : struct, IConvertible, IComparable, IFormattable
    {
        if (!typeof(TEnum).IsEnum)
            throw new ArgumentException("TEnum must be an Enumeration type");

        var res = from e in Enum.GetValues(typeof(TEnum)).Cast<TEnum>()
                    select new ValueName() { Value = Convert.ToInt32(e), Name = e.ToString()};

        return res;
    }

}

public struct ValueName
{
    public int Value { get; set; }
    public string Name { get; set; }
}

then you just do :

EnumHelper.GetItems<myEnum>()

6 Comments

I like your generic solution. But I need the Value property to be of type int, and I am unable to cast: select new ValueName() { Value = (int)e, Name = e.toString() }. Suggestions ?
It gives error - Cannot cast expression of type 'System.Enum' to type TEnum.
No, same error. Thanks anyway. I will go with Daniel Hilgarth way. Really like your approach though.
To make it work, simply replace Cast<Enum> with Cast<TEnum> and remove the strange GetEnumInt method with a simple Convert.ToInt32. Check my answer for reference.
Updated the answer to the working one, thanks @DanielHilgarth
|
2

Your code was very good, but I was change bit level simplification for your code.

Enum class (Does Not changed):

public enum myEnum
{
    IBM = 1,
    HP = 2,
    Lenovo = 3
}

Brand class(Change parameter length, you can pass one parameter of Enum):

public class Brand
{
    public Brand(Enum Data)
    {
        Name = Data.ToString();
        Id = Convert.ToInt32(Data); 
    }

    public string Name { get; private set; }
    public int Id { get; private set; }
}

And here is change this way:

private IEnumerable<Brand> brands = new List<Brand>
{
    new Brand(myEnum.IBM),
    new Brand(myEnum.HP),
    new Brand(myEnum.Lenovo),
};

And You like see this sample : C# Iterating through an enum? (Indexing a System.Array)

1 Comment

Thank You for your answer, Ramesh! I believe with my way the Brand class interface and usage is more clearer - it accepts name and id and initialize the corresponding properties.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.