136

I have the following code:

// Obtain the string names of all the elements within myEnum 
String[] names = Enum.GetNames( typeof( myEnum ) );

// Obtain the values of all the elements within myEnum 
Array values = Enum.GetValues( typeof( myEnum ) );

// Print the names and values to file
for ( int i = 0; i < names.Length; i++ )
{
    print( names[i], values[i] ); 
}

However, I cannot index values. Is there an easier way to do this?

Or have I missed something entirely!

0

13 Answers 13

235
Array values = Enum.GetValues(typeof(myEnum));

foreach( MyEnum val in values )
{
   Console.WriteLine (String.Format("{0}: {1}", Enum.GetName(typeof(MyEnum), val), val));
}

Or, you can cast the System.Array that is returned:

string[] names = Enum.GetNames(typeof(MyEnum));
MyEnum[] values = (MyEnum[])Enum.GetValues(typeof(MyEnum));

for( int i = 0; i < names.Length; i++ )
{
    print(names[i], values[i]);
}

But, can you be sure that GetValues returns the values in the same order as GetNames returns the names ?

Sign up to request clarification or add additional context in comments.

6 Comments

"But, can you be sure that GetValues returns the values in the same order as GetNames returns the names ?" -- This is a very good point and something I have yet to address! I think your first solution would probably provide a way to match values and strings reliably
Hello, I've seen mention before of this suspicion of "index-mismatching" occurring when doing this; however, I've yet to discover whether this really is a concern or not? Are there any definitive cases whereby this assumption may go awry? Thx!
You probably want to cast the second "val" to an int, if you want to troubleshoot value mismatch as in Enum.GetName(typeof(MyEnum), val), (int)val) in which the output provides the enumeration name and number.
GetValues and GetNames return in the same order, namely: "The elements of the return value array are sorted by the binary values of the enumerated constants (that is, by their unsigned magnitude)."
I believe you can also use LINQ directly by calling Cast<T> on the result: Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()...
|
36

You need to cast the array - the returned array is actually of the requested type, i.e. myEnum[] if you ask for typeof(myEnum):

myEnum[] values = (myEnum[]) Enum.GetValues(typeof(myEnum));

Then values[0] etc

Comments

10

You can cast that Array to different types of Arrays:

myEnum[] values = (myEnum[])Enum.GetValues(typeof(myEnum));

or if you want the integer values:

int[] values = (int[])Enum.GetValues(typeof(myEnum));

You can iterate those casted arrays of course :)

Comments

8

How about a dictionary list?

Dictionary<string, int> list = new Dictionary<string, int>();
foreach( var item in Enum.GetNames(typeof(MyEnum)) )
{
    list.Add(item, (int)Enum.Parse(typeof(MyEnum), item));
}

and of course you can change the dictionary value type to whatever your enum values are.

2 Comments

I think that this would be the way to go, but unfortucatly the enum is in an area of code which I have no control over!
The only solution I've found that gets the actual integer enum values!
4

What about using a foreach loop, maybe you could work with that?

  int i = 0;
  foreach (var o in values)
  {
    print(names[i], o);
    i++;
  }

something like that perhaps?

2 Comments

I have thaught of that ... but I need to get access to both names and values in 'sync' ... say the names[2] is paired with values[2] and I am unsure as to how to achieve this in a foreach loop!
I've added an example - see if that helps.
4

Here is another. We had a need to provide friendly names for our EnumValues. We used the System.ComponentModel.DescriptionAttribute to show a custom string value for each enum value.

public static class StaticClass
{
    public static string GetEnumDescription(Enum currentEnum)
    {
        string description = String.Empty;
        DescriptionAttribute da;

        FieldInfo fi = currentEnum.GetType().
                    GetField(currentEnum.ToString());
        da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi,
                    typeof(DescriptionAttribute));
        if (da != null)
            description = da.Description;
        else
            description = currentEnum.ToString();

        return description;
    }

    public static List<string> GetEnumFormattedNames<TEnum>()
    {
        var enumType = typeof(TEnum);
        if (enumType == typeof(Enum))
            throw new ArgumentException("typeof(TEnum) == System.Enum", "TEnum");

        if (!(enumType.IsEnum))
            throw new ArgumentException(String.Format("typeof({0}).IsEnum == false", enumType), "TEnum");

        List<string> formattedNames = new List<string>();
        var list = Enum.GetValues(enumType).OfType<TEnum>().ToList<TEnum>();

        foreach (TEnum item in list)
        {
            formattedNames.Add(GetEnumDescription(item as Enum));
        }

        return formattedNames;
    }
}

In Use

 public enum TestEnum
 { 
        [Description("Something 1")]
        Dr = 0,
        [Description("Something 2")]
        Mr = 1
 }



    static void Main(string[] args)
    {

        var vals = StaticClass.GetEnumFormattedNames<TestEnum>();
    }

This will end returning "Something 1", "Something 2"

1 Comment

Only good if the descriptions are static... if your descriptions need to change based on an instance basis then this approach won't work.
4

Another solution, with interesting possibilities:

enum Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }

static class Helpers
{
public static IEnumerable<Days> AllDays(Days First)
{
  if (First == Days.Monday)
  {
     yield return Days.Monday;
     yield return Days.Tuesday;
     yield return Days.Wednesday;
     yield return Days.Thursday;
     yield return Days.Friday;
     yield return Days.Saturday;
     yield return Days.Sunday;
  } 

  if (First == Days.Saturday)
  {
     yield return Days.Saturday;
     yield return Days.Sunday;
     yield return Days.Monday;
     yield return Days.Tuesday;
     yield return Days.Wednesday;
     yield return Days.Thursday;
     yield return Days.Friday;
  } 
}

Comments

4

Old question, but a slightly cleaner approach using LINQ's .Cast<>()

var values = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>();

foreach(var val in values)
{
    Console.WriteLine("Member: {0}",val.ToString());     
}

Comments

4

In the Enum.GetValues results, casting to int produces the numeric value. Using ToString() produces the friendly name. No other calls to Enum.GetName are needed.

public enum MyEnum
{
    FirstWord,
    SecondWord,
    Another = 5
};

// later in some method  

 StringBuilder sb = new StringBuilder();
 foreach (var val in Enum.GetValues(typeof(MyEnum))) {
   int numberValue = (int)val;
   string friendyName = val.ToString();
   sb.Append("Enum number " + numberValue + " has the name " + friendyName + "\n");
 }
 File.WriteAllText(@"C:\temp\myfile.txt", sb.ToString());

 // Produces the output file contents:
 /*
 Enum number 0 has the name FirstWord
 Enum number 1 has the name SecondWord
 Enum number 5 has the name Another
 */

Comments

2

Array has a GetValue(Int32) method which you can use to retrieve the value at a specified index.

Array.GetValue

Comments

2

You can simplify this using format strings. I use the following snippet in usage messages:

writer.WriteLine("Exit codes are a combination of the following:");
foreach (ExitCodes value in Enum.GetValues(typeof(ExitCodes)))
{
    writer.WriteLine("   {0,4:D}: {0:G}", value);
}

The D format specifier formats the enum value as a decimal. There's also an X specifier that gives hexadecimal output.

The G specifier formats an enum as a string. If the Flags attribute is applied to the enum then combined values are supported as well. There's an F specifier that acts as if Flags is always present.

See Enum.Format().

Comments

0

Here is a simple way to iterate through your custom Enum object

For Each enumValue As Integer In [Enum].GetValues(GetType(MyEnum))

     Print([Enum].GetName(GetType(MyEnum), enumValue).ToString)

Next

Comments

0

Ancient question, but 3Dave's answer supplied the easiest approach. I needed a little helper method to generate a Sql script to decode an enum value in the database for debugging. It worked great:

    public static string EnumToCheater<T>() {
        var sql = "";
        foreach (var enumValue in Enum.GetValues(typeof(T)))
            sql += $@"when {(int) enumValue} then '{enumValue}' ";
        return $@"case ?? {sql}else '??' end,";
    }

I have it in a static method, so usage is:

var cheater = MyStaticClass.EnumToCheater<MyEnum>()

Comments

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.