Reputation: 256571
How can you enumerate an enum
in C#?
E.g. the following code does not compile:
public enum Suit
{
Spades,
Hearts,
Clubs,
Diamonds
}
public void EnumerateAllSuitsDemoMethod()
{
foreach (Suit suit in Suit)
{
DoSomething(suit);
}
}
And it gives the following compile-time error:
'Suit' is a 'type' but is used like a 'variable'
It fails on the Suit
keyword, the second one.
Upvotes: 4409
Views: 1058314
Reputation: 619
There is one essential flaw in other answers: some problems when your enumeration type has members with explicitly defined values, and if some values get identical values. Those identical values are sometimes used to provide synonyms. Besides, sometimes you need to exclude some auxiliary members for the traversal.
For a comprehensive solution with a number of extras please see my article Enumeration Types do not Enumerate! Working around .NET and Language Limitations. In other articles of my enumeration series referenced in this article, you can find some interesting applications of this approach.
Upvotes: 0
Reputation: 1439
I think you can use Enum.GetNames(Type enumType)
method to retrieve an array of the names of the constants in a specified enumeration.
string[] suits = Enum.GetNames(typeof(Suit));
or the generic alternative:
string[] suits = Enum.GetNames<Suit>();
https://learn.microsoft.com/en-us/dotnet/api/system.enum.getnames
Upvotes: 73
Reputation: 403
Create an Extension for converting any enum to a list for binding to control by datasource
public class KeyValueViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
public static List<KeyValueViewModel> ConvertToList(this Enum en)
{
return ((KeyValueViewModel[])Enum.GetValues(en.GetType())).Select(c => new KeyValueViewModel() { Id = c.Id, Name = c.ToString() }).ToList();
}
Upvotes: 1
Reputation: 12685
.NET 5 has introduced a new generic version for the GetValues
method:
Suit[] suitValues = Enum.GetValues<Suit>();
Which is now by far the most convenient way of doing this.
Usage in a foreach loop:
foreach (Suit suit in Enum.GetValues<Suit>())
{
}
And if you just need the enum names as strings, you can use the GetNames
method instead:
string[] suitNames = Enum.GetNames<Suit>();
Upvotes: 195
Reputation: 84043
Update: If you're using .NET 5 or newer, use this solution.
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.
Upvotes: 5316
Reputation: 800
For a future reader:
I do it this way:
public static class EnumHelpers
{
public static Dictionary<TEnum, string> ToDictionary<TEnum>() where TEnum:Enum
{
var values = (TEnum[])Enum.GetValues(typeof(TEnum));
return values
.Select(v => (value: v, name: v.ToString()))
.ToDictionary(vv=>vv.value, vn=>vn.name);
}
}
public enum Suit
{
Clubs, Diamonds, Hearts, Spades
}
Then, in some function, use it like this:
var Suits = EnumHelpers.ToDictionary<Suit>();
Suits
is a Dictionary<Suit, string>
.
There may need to be an additional check to get rid of the repeating values, maybe a call to Distinct()
on values
. Or the name could be used as the key, that way each name is unique even if a value repeats. Adjust as needed.
Upvotes: 3
Reputation: 2803
When you have a bit enum like this
enum DemoFlags
{
DemoFlag = 1,
OtherFlag = 2,
TestFlag = 4,
LastFlag = 8,
}
With this assignement
DemoFlags demoFlags = DemoFlags.DemoFlag | DemoFlags.TestFlag;
and need a result like this
"DemoFlag | TestFlag"
this method helps:
public static string ConvertToEnumString<T>(T enumToConvert, string separator = " | ") where T : Enum
{
StringBuilder convertedEnums = new StringBuilder();
foreach (T enumValue in Enum.GetValues(typeof(T)))
{
if (enumToConvert.HasFlag(enumValue)) convertedEnums.Append($"{ enumValue }{separator}");
}
if (convertedEnums.Length > 0) convertedEnums.Length -= separator.Length;
return convertedEnums.ToString();
}
Upvotes: 5
Reputation: 486
I think its help you try it.
public class Program
{
public static List<T> GetEnamList<T>()
{
var enums = Enum.GetValues(typeof(T)).Cast<T>().Select(v => v).ToList();
return enums;
}
private void LoadEnumList()
{
List<DayofWeek> dayofweeks = GetEnamList<DayofWeek>();
foreach (var item in dayofweeks)
{
dayofweeks.Add(item);
}
}
}
public enum DayofWeek
{
Monday,
Tuesday,
Wensday,
Thursday,
Friday,
Sturday,
Sunday
}
Upvotes: 3
Reputation: 760
For getting a list of int from an enum, use the following. It works!
List<int> listEnumValues = new List<int>();
YourEnumType[] myEnumMembers = (YourEnumType[])Enum.GetValues(typeof(YourEnumType));
foreach ( YourEnumType enumMember in myEnumMembers)
{
listEnumValues.Add(enumMember.GetHashCode());
}
Upvotes: 7
Reputation: 606
Add method public static IEnumerable<T> GetValues<T>()
to your class, like:
public static IEnumerable<T> GetValues<T>()
{
return Enum.GetValues(typeof(T)).Cast<T>();
}
Call and pass your enum. Now you can iterate through it using foreach
:
public static void EnumerateAllSuitsDemoMethod()
{
// Custom method
var foos = GetValues<Suit>();
foreach (var foo in foos)
{
// Do something
}
}
Upvotes: 18
Reputation: 8803
There are two ways to iterate an Enum
:
1. var values = Enum.GetValues(typeof(myenum))
2. var values = Enum.GetNames(typeof(myenum))
The first will give you values in form on an array of **object
**s, and the second will give you values in form of an array of **String
**s.
Use it in a foreach
loop as below:
foreach(var value in values)
{
// Do operations here
}
Upvotes: 37
Reputation: 17498
I know it is a bit messy, but if you are fan of one-liners, here is one:
((Suit[])Enum.GetValues(typeof(Suit))).ToList().ForEach(i => DoSomething(i));
Upvotes: 14
Reputation: 73153
Three ways:
Enum.GetValues(type)
// Since .NET 1.1, not in Silverlight or .NET Compact Frameworktype.GetEnumValues()
// Only on .NET 4 and abovetype.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null))
// Works everywhereI am not sure why GetEnumValues
was introduced on type instances. It isn't very readable at all for me.
Having a helper class like Enum<T>
is what is most readable and memorable for me:
public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
public static IEnumerable<T> GetValues()
{
return (T[])Enum.GetValues(typeof(T));
}
public static IEnumerable<string> GetNames()
{
return Enum.GetNames(typeof(T));
}
}
Now you call:
Enum<Suit>.GetValues();
// Or
Enum.GetValues(typeof(Suit)); // Pretty consistent style
One can also use some sort of caching if performance matters, but I don't expect this to be an issue at all.
public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
// Lazily loaded
static T[] values;
static string[] names;
public static IEnumerable<T> GetValues()
{
return values ?? (values = (T[])Enum.GetValues(typeof(T)));
}
public static IEnumerable<string> GetNames()
{
return names ?? (names = Enum.GetNames(typeof(T)));
}
}
Upvotes: 41
Reputation: 1739
Just by combining the top answers, I threw together a very simple extension:
public static class EnumExtensions
{
/// <summary>
/// Gets all items for an enum value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value.</param>
/// <returns></returns>
public static IEnumerable<T> GetAllItems<T>(this T value) where T : Enum
{
return (T[])Enum.GetValues(typeof (T));
}
}
It is clean, simple, and, by @Jeppe-Stig-Nielsen's comment, fast.
Upvotes: 42
Reputation: 11439
Use Cast<T>
:
var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>();
There you go, IEnumerable<Suit>
.
Upvotes: 149
Reputation: 73153
If enum values range strictly from 0 to n - 1, a generic alternative is:
public void EnumerateEnum<T>()
{
int length = Enum.GetValues(typeof(T)).Length;
for (var i = 0; i < length; i++)
{
var @enum = (T)(object)i;
}
}
If enum values are contiguous and you can provide the first and last element of the enum, then:
public void EnumerateEnum()
{
for (var i = Suit.Spade; i <= Suit.Diamond; i++)
{
var @enum = i;
}
}
But that's not strictly enumerating, just looping. The second method is much faster than any other approach though...
Upvotes: 20
Reputation: 12419
Here is a working example of creating select options for a DDL:
var resman = ViewModelResources.TimeFrame.ResourceManager;
ViewBag.TimeFrames = from MapOverlayTimeFrames timeFrame
in Enum.GetValues(typeof(MapOverlayTimeFrames))
select new SelectListItem
{
Value = timeFrame.ToString(),
Text = resman.GetString(timeFrame.ToString()) ?? timeFrame.ToString()
};
Upvotes: 18
Reputation: 6103
I think this is more efficient than other suggestions because GetValues()
is not called each time you have a loop. It is also more concise. And you get a compile-time error, not a runtime exception if Suit
is not an enum
.
EnumLoop<Suit>.ForEach((suit) => {
DoSomethingWith(suit);
});
EnumLoop
has this completely generic definition:
class EnumLoop<Key> where Key : struct, IConvertible {
static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key));
static internal void ForEach(Action<Key> act) {
for (int i = 0; i < arr.Length; i++) {
act(arr[i]);
}
}
}
Upvotes: 114
Reputation: 911
You won't get Enum.GetValues()
in Silverlight.
Original Blog Post by Einar Ingebrigtsen:
public class EnumHelper
{
public static T[] GetValues<T>()
{
Type enumType = typeof(T);
if (!enumType.IsEnum)
{
throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
}
List<T> values = new List<T>();
var fields = from field in enumType.GetFields()
where field.IsLiteral
select field;
foreach (FieldInfo field in fields)
{
object value = field.GetValue(enumType);
values.Add((T)value);
}
return values.ToArray();
}
public static object[] GetValues(Type enumType)
{
if (!enumType.IsEnum)
{
throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
}
List<object> values = new List<object>();
var fields = from field in enumType.GetFields()
where field.IsLiteral
select field;
foreach (FieldInfo field in fields)
{
object value = field.GetValue(enumType);
values.Add(value);
}
return values.ToArray();
}
}
Upvotes: 91
Reputation: 1499
My solution works in .NET Compact Framework (3.5) and supports type checking at compile time:
public static List<T> GetEnumValues<T>() where T : new() {
T valueType = new T();
return typeof(T).GetFields()
.Select(fieldInfo => (T)fieldInfo.GetValue(valueType))
.Distinct()
.ToList();
}
public static List<String> GetEnumNames<T>() {
return typeof (T).GetFields()
.Select(info => info.Name)
.Distinct()
.ToList();
}
T valueType = new T()
, I'd be happy to see a solution.A call would look like this:
List<MyEnum> result = Utils.GetEnumValues<MyEnum>();
Upvotes: 71
Reputation: 6485
I made some extensions for easy enum usage. Maybe someone can use it...
public static class EnumExtensions
{
/// <summary>
/// Gets all items for an enum value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value.</param>
/// <returns></returns>
public static IEnumerable<T> GetAllItems<T>(this Enum value)
{
foreach (object item in Enum.GetValues(typeof(T)))
{
yield return (T)item;
}
}
/// <summary>
/// Gets all items for an enum type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value.</param>
/// <returns></returns>
public static IEnumerable<T> GetAllItems<T>() where T : struct
{
foreach (object item in Enum.GetValues(typeof(T)))
{
yield return (T)item;
}
}
/// <summary>
/// Gets all combined items from an enum value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value">The value.</param>
/// <returns></returns>
/// <example>
/// Displays ValueA and ValueB.
/// <code>
/// EnumExample dummy = EnumExample.Combi;
/// foreach (var item in dummy.GetAllSelectedItems<EnumExample>())
/// {
/// Console.WriteLine(item);
/// }
/// </code>
/// </example>
public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value)
{
int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
foreach (object item in Enum.GetValues(typeof(T)))
{
int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture);
if (itemAsInt == (valueAsInt & itemAsInt))
{
yield return (T)item;
}
}
}
/// <summary>
/// Determines whether the enum value contains a specific value.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="request">The request.</param>
/// <returns>
/// <c>true</c> if value contains the specified value; otherwise, <c>false</c>.
/// </returns>
/// <example>
/// <code>
/// EnumExample dummy = EnumExample.Combi;
/// if (dummy.Contains<EnumExample>(EnumExample.ValueA))
/// {
/// Console.WriteLine("dummy contains EnumExample.ValueA");
/// }
/// </code>
/// </example>
public static bool Contains<T>(this Enum value, T request)
{
int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture);
if (requestAsInt == (valueAsInt & requestAsInt))
{
return true;
}
return false;
}
}
The enum itself must be decorated with the FlagsAttribute:
[Flags]
public enum EnumExample
{
ValueA = 1,
ValueB = 2,
ValueC = 4,
ValueD = 8,
Combi = ValueA | ValueB
}
Upvotes: 393
Reputation: 5383
LINQ Generic Way:
public static Dictionary<int, string> ToList<T>() where T : struct =>
((IEnumerable<T>)Enum.GetValues(typeof(T))).ToDictionary(value => Convert.ToInt32(value), value => value.ToString());
Usage:
var enums = ToList<Enum>();
Upvotes: 1
Reputation: 1104
If you have:
enum Suit
{
Spades,
Hearts,
Clubs,
Diamonds
}
This:
foreach (var e in Enum.GetValues(typeof(Suit)))
{
Console.WriteLine(e.ToString() + " = " + (int)e);
}
Will output:
Spades = 0
Hearts = 1
Clubs = 2
Diamonds = 3
Upvotes: 3
Reputation: 3033
Some versions of the .NET framework do not support Enum.GetValues
. Here's a good workaround from Ideas 2.0: Enum.GetValues in Compact Framework:
public Enum[] GetValues(Enum enumeration)
{
FieldInfo[] fields = enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public);
Enum[] enumerations = new Enum[fields.Length];
for (var i = 0; i < fields.Length; i++)
enumerations[i] = (Enum) fields[i].GetValue(enumeration);
return enumerations;
}
As with any code that involves reflection, you should take steps to ensure it runs only once and results are cached.
Upvotes: 205
Reputation: 166
enum
types are called "enumeration types" not because they are containers that "enumerate" values (which they aren't), but because they are defined by enumerating the possible values for a variable of that type.
(Actually, that's a bit more complicated than that - enum types are considered to have an "underlying" integer type, which means each enum value corresponds to an integer value (this is typically implicit, but can be manually specified). C# was designed in a way so that you could stuff any integer of that type into the enum variable, even if it isn't a "named" value.)
The System.Enum.GetNames method can be used to retrieve an array of strings which are the names of the enum values, as the name suggests.
EDIT: Should have suggested the System.Enum.GetValues method instead. Oops.
Upvotes: 6
Reputation: 7768
foreach (Suit suit in Enum.GetValues(typeof(Suit))) { }
I've heard vague rumours that this is terifically slow. Anyone know? – Orion Edwards Oct 15 '08 at 1:31 7
I think caching the array would speed it up considerably. It looks like you're getting a new array (through reflection) every time. Rather:
Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums)
{
DoSomething(suitEnum);
}
That's at least a little faster, ja?
Upvotes: 59
Reputation: 679
This question appears in Chapter 10 of "C# Step by Step 2013"
The author uses a double for-loop to iterate through a pair of Enumerators (to create a full deck of cards):
class Pack
{
public const int NumSuits = 4;
public const int CardsPerSuit = 13;
private PlayingCard[,] cardPack;
public Pack()
{
this.cardPack = new PlayingCard[NumSuits, CardsPerSuit];
for (Suit suit = Suit.Clubs; suit <= Suit.Spades; suit++)
{
for (Value value = Value.Two; value <= Value.Ace; value++)
{
cardPack[(int)suit, (int)value] = new PlayingCard(suit, value);
}
}
}
}
In this case, Suit
and Value
are both enumerations:
enum Suit { Clubs, Diamonds, Hearts, Spades }
enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}
and PlayingCard
is a card object with a defined Suit
and Value
:
class PlayingCard
{
private readonly Suit suit;
private readonly Value value;
public PlayingCard(Suit s, Value v)
{
this.suit = s;
this.value = v;
}
}
Upvotes: 13
Reputation: 7036
Also you can bind to the public static members of the enum directly by using reflection:
typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
.ToList().ForEach(x => DoSomething(x.Name));
Upvotes: 3
Reputation: 2746
public void PrintAllSuits()
{
foreach(string suit in Enum.GetNames(typeof(Suits)))
{
Console.WriteLine(suit);
}
}
Upvotes: 61
Reputation: 897
A simple and generic way to convert an enum to something you can interact:
public static Dictionary<int, string> ToList<T>() where T : struct
{
return ((IEnumerable<T>)Enum
.GetValues(typeof(T)))
.ToDictionary(
item => Convert.ToInt32(item),
item => item.ToString());
}
And then:
var enums = EnumHelper.ToList<MyEnum>();
Upvotes: 13