How to Loop Through All Enum Values in C#

How to loop through all enum values in C#?

Yes you can use the ‍GetValue‍‍‍s method:

var values = Enum.GetValues(typeof(Foos));

Or the typed version:

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

I long ago added a helper function to my private library for just such an occasion:

public static class EnumUtil {
public static IEnumerable<T> GetValues<T>() {
return Enum.GetValues(typeof(T)).Cast<T>();
}
}

Usage:

var values = EnumUtil.GetValues<Foos>();

How to enumerate an enum


foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

Note: The cast to (Suit[]) is not strictly necessary, but it does make the code 0.5 ns faster.

Loop through a C# enum's keys AND values

The Enum class has the Methods you're looking for.

foreach(int i in Enum.GetValues(typeof(stuff)))
{
String name = Enum.GetName(typeof(stuff), i);
NewObject thing = new NewObject
{
Name = name,
Number = i
};
}

Is there a way to iterate through all enum values?


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

Then just populate the dropdown withe the array

Loop through all enum values with multiple non unique numbers

You can obtain all the enums names and filter those which match the value

Code:

private static string LongName<T>(long value) where T : Enum {
unchecked {
return string.Join(" or ", Enum
.GetNames(typeof(T))
.Where(name => Convert.ToInt64(Enum.Parse(typeof(MyEnum), name)) == value)
.OrderBy(name => name));
}
}

private static string LongAttributeName<T>(long value) where T : Enum {
unchecked {
return string.Join(" or ", Enum
.GetNames(typeof(T))
.Where(name => Convert.ToInt64(Enum.Parse(typeof(MyEnum), name)) == value)
.Select(name => typeof(T)
.GetMember(name)
.FirstOrDefault(mi => mi.DeclaringType == typeof(T)))
.SelectMany(mi => mi.GetCustomAttributes<CategoryEnumAttribute>(false))
.Select(attr => attr.Description) //TODO: Put the right property here
.OrderBy(name => name));
}
}

private static string[] LongNames<T>() where T : Enum {
unchecked {
return Enum
.GetNames(typeof(T))
.OrderBy(name => Convert.ToInt64(Enum.Parse(typeof(MyEnum), name)))
.ThenBy(name => name)
.ToArray();
}
}

private static string[] LongNamesCombined<T>() where T : Enum {
unchecked {
return Enum
.GetNames(typeof(T))
.GroupBy(name => Convert.ToInt64(Enum.Parse(typeof(MyEnum), name)))
.OrderBy(group => group.Key)
.Select(group => string.Join(" or ", group.OrderBy(name => name)))
.ToArray();
}
}

Demo:

// Single Value
Console.Write(LongName<MyEnum>(1));
// Single Value attributes
Console.Write(LongAttributeName<MyEnum>(1));
// All Values (array with 4 items)
Console.Write(string.Join(", ", LongNames<MyEnum>()));
// All Values combined (array with 2 items)
Console.Write(string.Join(", ", LongNamesCombined<MyEnum>()));

Outcome:

Red or Strong
Color or Attributes # <- Depends on implementation
Red, Strong, Blue, Weak
Red or Strong, Blue or Weak

c# loop through all fields of enum assigning values from string array

Why not place the values onto the enum itself and then enumerate?

For example using System.ComponentModel Description attribute we can add that information to the enum itself such as:

public enum cardCreate
{
[Description("General Response")]
MsgType = 0,

[Description("V2.0")]
WSName = 2,

[Description("OmegaMan")]
ReplyTo = 3,

[Description("Windows 10")]
SourceSystem = 4,
}

So when we call a special method to enumerate the enum where we can extract that text and use it appropriately later such as:

myextensions.GetEnumValues<cardCreate>()
.Select (ceEnum => new
{
Original = ceEnum,
IndexValue = (int)ceEnum,
Text = ceEnum.GetAttributeDescription()
})

The dynamic entity will look like this after the projection (the select):

Sample Image

Sweet! Now we have all the information in a easy consumable entity which provides all the information needed.

What? You need more than a string description? Then create a custom attribute on the enum and have all items/types of data to return as needed. For that see my blog article C# Using Extended Attribute Information on Objects.


Here are the extension methods used in the above example:

public static class myextensions
{
public static IEnumerable<T> GetEnumValues<T>()
{
Type type = typeof( T );

if (!type.IsEnum)
throw new Exception( string.Format("{0} is not an enum.", type.FullName ));

FieldInfo[] fields =
type.GetFields( BindingFlags.Public | BindingFlags.Static );


foreach (var item in fields)
yield return (T)item.GetValue( null );
}


/// <summary>If an attribute on an enumeration exists, this will return that
/// information</summary>
/// <param name="value">The object which has the attribute.</param>
/// <returns>The description string of the attribute or string.empty</returns>
public static string GetAttributeDescription( this object value )
{
string retVal = string.Empty;
try
{
retVal = value.GetType()
.GetField( value.ToString() )
.GetCustomAttributes( typeof( DescriptionAttribute ), false )
.OfType<DescriptionAttribute>()
.First()
.Description;

}
catch (NullReferenceException)
{
//Occurs when we attempt to get description of an enum value that does not exist
}
finally
{
if (string.IsNullOrEmpty( retVal ))
retVal = "Unknown";
}

return retVal;
}

}

C# Iterating through an enum? (Indexing a System.Array)


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 ?

Iterate Between Enum Values in C#

This will work:

for(Cars car=Cars.Opel; car<=Cars.Citroen; car++)
{
Console.WriteLine(car);
}

but you have to make sure that the start value is less than the end value.

EDIT

If you don't hardcode the start and end, but supply them as parameters, you need to use them in the correct order. If you just switch "Opel" and "Citroen", you will get no output.

Also (as remarked in the comments) the underlying integer values must not contain gaps or overlaps. Luckily if you do not specify values yourself (even the '=0' is not needed), this will be the default behaviour. See MSDN:

When you do not specify values for the elements in the enumerator list, the values are automatically incremented by 1.


Loop through selected Enum values?

How about the following:

FileStatus status = FileStatus.New|FileStatus.Amazing;

foreach (FileStatus x in Enum.GetValues(typeof(FileStatus)))
{
if (status.HasFlag(x)) Console.WriteLine("{0} set", x);
}

Or in one fell LINQ swoop:

var flags = Enum.GetValues(typeof(FileStatus))
.Cast<FileStatus>()
.Where(s => status.HasFlag(s));


Related Topics



Leave a reply



Submit