C# 有没有办法遍历所有枚举值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/154256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 15:56:23  来源:igfitidea点击:

Is there a way to iterate through all enum values?

提问by vIceBerg

Possible Duplicate:
C#: How to enumerate an enum?

可能的重复:
C#:如何枚举枚举?

The subject says all. I want to use that to add the values of an enum in a combobox.

题目说明了一切。我想用它在组合框中添加枚举的值。

Thanks

谢谢

vIceBerg

卑诗

采纳答案by albertein

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

Then just populate the dropdown withe the array

然后用数组填充下拉列表

回答by JosephStyons

It is often useful to define a Min and Max inside your enum, which will always be the first and last items. Here is a very simple example using Delphi syntax:

在枚举中定义 Min 和 Max 通常很有用,它们始终是第一个和最后一个项目。这是一个使用 Delphi 语法的非常简单的示例:

procedure TForm1.Button1Click(Sender: TObject);
type
  TEmployeeTypes = (etMin, etHourly, etSalary, etContractor, etMax);
var
  i : TEmployeeTypes;
begin
  for i := etMin to etMax do begin
    //do something
  end;
end;

回答by Firas Assaad

You could iterate through the array returned by the Enum.GetNames methodinstead.

您可以迭代Enum.GetNames 方法返回的数组。

public class GetNamesTest {
    enum Colors { Red, Green, Blue, Yellow };
    enum Styles { Plaid, Striped, Tartan, Corduroy };

    public static void Main() {

        Console.WriteLine("The values of the Colors Enum are:");
        foreach(string s in Enum.GetNames(typeof(Colors)))
            Console.WriteLine(s);

        Console.WriteLine();

        Console.WriteLine("The values of the Styles Enum are:");
        foreach(string s in Enum.GetNames(typeof(Styles)))
            Console.WriteLine(s);
    }
}

回答by Lasse V. Karlsen

Use the Enum.GetValues method:

使用 Enum.GetValues 方法:

foreach (TestEnum en in Enum.GetValues(typeof(TestEnum)))
{
    ...
}

You don't need to cast them to a string, and that way you can just retrieve them back by casting the SelectedItem property to a TestEnum value directly as well.

您不需要将它们转换为字符串,这样您也可以通过将 SelectedItem 属性直接转换为 TestEnum 值来检索它们。

回答by rslite

If you need the values of the combo to correspond to the values of the enum you can also use something like this:

如果您需要组合的值与枚举的值相对应,您还可以使用以下内容:

foreach (TheEnum value in Enum.GetValues(typeof(TheEnum)))
    dropDown.Items.Add(new ListItem(
        value.ToString(), ((int)value).ToString()
    );

In this way you can show the texts in the dropdown and obtain back the value (in SelectedValue property)

通过这种方式,您可以在下拉列表中显示文本并获取值(在 SelectedValue 属性中)

回答by Ray Hayes

I know others have already answered with a correct answer, however, if you're wanting to use the enumerations in a combo box, you may want to go the extra yard and associate strings to the enum so that you can provide more detail in the displayed string (such as spaces between words or display strings using casing that doesn't match your coding standards)

我知道其他人已经回答了正确的答案,但是,如果您想在组合框中使用枚举,您可能需要额外的码并将字符串与枚举相关联,以便您可以在显示的字符串(例如单词之间的空格或使用与您的编码标准不匹配的大小写的显示字符串)

This blog entry may be useful - Associating Strings with enums in c#

此博客条目可能有用 - 将字符串与 c# 中的枚举关联起来

public enum States
{
    California,
    [Description("New Mexico")]
    NewMexico,
    [Description("New York")]
    NewYork,
    [Description("South Carolina")]
    SouthCarolina,
    Tennessee,
    Washington
}

As a bonus, he also supplied a utility method for enumerating the enumeration that I've now updated with Jon Skeet's comments

作为奖励,他还提供了一个实用方法来枚举我现在用 Jon Skeet 的评论更新的枚举

public static IEnumerable<T> EnumToList<T>()
    where T : struct
{
    Type enumType = typeof(T);

    // Can't use generic type constraints on value types,
    // so have to do check like this
    if (enumType.BaseType != typeof(Enum))
        throw new ArgumentException("T must be of type System.Enum");

    Array enumValArray = Enum.GetValues(enumType);
    List<T> enumValList = new List<T>();

    foreach (T val in enumValArray)
    {
        enumValList.Add(val.ToString());
    }

    return enumValList;
}

Jon also pointed out that in C# 3.0 it can be simplified to something like this (which is now getting so light-weight that I'd imagine you could just do it in-line):

Jon 还指出,在 C# 3.0 中,它可以简化为这样的东西(现在它变得如此轻量级,我想你可以直接使用它):

public static IEnumerable<T> EnumToList<T>()
    where T : struct
{
    return Enum.GetValues(typeof(T)).Cast<T>();
}

// Using above method
statesComboBox.Items = EnumToList<States>();

// Inline
statesComboBox.Items = Enum.GetValues(typeof(States)).Cast<States>();

回答by Programmin Tool

Little more "complicated" (maybe overkill) but I use these two methods to return dictionaries to use as datasources. The first one returns the name as key and the second value as key.

稍微“复杂”一点(可能有点矫枉过正),但我使用这两种方法来返回字典以用作数据源。第一个返回名称作为键,第二个值作为键返回。

public static IDictionary<string, int> ConvertEnumToDictionaryNameFirst<K>()
{
  if (typeof(K).BaseType != typeof(Enum))
  {
    throw new InvalidCastException();
  }

  return Enum.GetValues(typeof(K)).Cast<int>().ToDictionary(currentItem 
    => Enum.GetName(typeof(K), currentItem));
}

Or you could do

或者你可以做

public static IDictionary<int, string> ConvertEnumToDictionaryValueFirst<K>()
{
  if (typeof(K).BaseType != typeof(Enum))
  {
    throw new InvalidCastException();
  }

  return Enum.GetNames(typeof(K)).Cast<string>().ToDictionary(currentItem 
    => (int)Enum.Parse(typeof(K), currentItem));
}

This assumes you are using 3.5 though. You'd have to replace the lambda expressions if not.

不过,这假设您使用的是 3.5。如果没有,您必须替换 lambda 表达式。

Use:

用:

  Dictionary list = ConvertEnumToDictionaryValueFirst<SomeEnum>();

  using System;
  using System.Collections.Generic;
  using System.Linq;

回答by Donny V.

The problem with using enums to populate pull downs is that you cann't have weird characters or spaces in enums. I have some code that extends enums so that you can add any character you want.

使用枚举填充下拉列表的问题在于枚举中不能有奇怪的字符或空格。我有一些扩展枚举的代码,以便您可以添加任何您想要的字符。

Use it like this..

像这样用..

public enum eCarType
{
    [StringValue("Saloon / Sedan")] Saloon = 5,
    [StringValue("Coupe")] Coupe = 4,
    [StringValue("Estate / Wagon")] Estate = 6,
    [StringValue("Hatchback")] Hatchback = 8,
    [StringValue("Utility")] Ute = 1,
}

Bind data like so..

像这样绑定数据..

StringEnum CarTypes = new StringEnum(typeof(eCarTypes));
cmbCarTypes.DataSource = CarTypes.GetGenericListValues();

Here is the class that extends the enum.

这是扩展枚举的类。

// Author: Donny V.
// blog: http://donnyvblog.blogspot.com

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

namespace xEnums
{

    #region Class StringEnum

    /// <summary>
    /// Helper class for working with 'extended' enums using <see cref="StringValueAttribute"/> attributes.
    /// </summary>
    public class StringEnum
    {
        #region Instance implementation

        private Type _enumType;
        private static Hashtable _stringValues = new Hashtable();

        /// <summary>
        /// Creates a new <see cref="StringEnum"/> instance.
        /// </summary>
        /// <param name="enumType">Enum type.</param>
        public StringEnum(Type enumType)
        {
            if (!enumType.IsEnum)
                throw new ArgumentException(String.Format("Supplied type must be an Enum.  Type was {0}", enumType.ToString()));

            _enumType = enumType;
        }

        /// <summary>
        /// Gets the string value associated with the given enum value.
        /// </summary>
        /// <param name="valueName">Name of the enum value.</param>
        /// <returns>String Value</returns>
        public string GetStringValue(string valueName)
        {
            Enum enumType;
            string stringValue = null;
            try
            {
                enumType = (Enum) Enum.Parse(_enumType, valueName);
                stringValue = GetStringValue(enumType);
            }
            catch (Exception) { }//Swallow!

            return stringValue;
        }

        /// <summary>
        /// Gets the string values associated with the enum.
        /// </summary>
        /// <returns>String value array</returns>
        public Array GetStringValues()
        {
            ArrayList values = new ArrayList();
            //Look for our string value associated with fields in this enum
            foreach (FieldInfo fi in _enumType.GetFields())
            {
                //Check for our custom attribute
                StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof (StringValueAttribute), false) as StringValueAttribute[];
                if (attrs.Length > 0)
                    values.Add(attrs[0].Value);

            }

            return values.ToArray();
        }

        /// <summary>
        /// Gets the values as a 'bindable' list datasource.
        /// </summary>
        /// <returns>IList for data binding</returns>
        public IList GetListValues()
        {
            Type underlyingType = Enum.GetUnderlyingType(_enumType);
            ArrayList values = new ArrayList();
            //List<string> values = new List<string>();

            //Look for our string value associated with fields in this enum
            foreach (FieldInfo fi in _enumType.GetFields())
            {
                //Check for our custom attribute
                StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof (StringValueAttribute), false) as StringValueAttribute[];
                if (attrs.Length > 0)
                    values.Add(new DictionaryEntry(Convert.ChangeType(Enum.Parse(_enumType, fi.Name), underlyingType), attrs[0].Value));

            }

            return values;

        }

        /// <summary>
        /// Gets the values as a 'bindable' list<string> datasource.
        ///This is a newer version of 'GetListValues()'
        /// </summary>
        /// <returns>IList<string> for data binding</returns>
        public IList<string> GetGenericListValues()
        {
            Type underlyingType = Enum.GetUnderlyingType(_enumType);
            List<string> values = new List<string>();

            //Look for our string value associated with fields in this enum
            foreach (FieldInfo fi in _enumType.GetFields())
            {
                //Check for our custom attribute
                StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
                if (attrs.Length > 0)
                    values.Add(attrs[0].Value);
            }

            return values;

        }

        /// <summary>
        /// Return the existence of the given string value within the enum.
        /// </summary>
        /// <param name="stringValue">String value.</param>
        /// <returns>Existence of the string value</returns>
        public bool IsStringDefined(string stringValue)
        {
            return Parse(_enumType, stringValue) != null;
        }

        /// <summary>
        /// Return the existence of the given string value within the enum.
        /// </summary>
        /// <param name="stringValue">String value.</param>
        /// <param name="ignoreCase">Denotes whether to conduct a case-insensitive match on the supplied string value</param>
        /// <returns>Existence of the string value</returns>
        public bool IsStringDefined(string stringValue, bool ignoreCase)
        {
            return Parse(_enumType, stringValue, ignoreCase) != null;
        }

        /// <summary>
        /// Gets the underlying enum type for this instance.
        /// </summary>
        /// <value></value>
        public Type EnumType
        {
            get { return _enumType; }
        }

        #endregion

        #region Static implementation

        /// <summary>
        /// Gets a string value for a particular enum value.
        /// </summary>
        /// <param name="value">Value.</param>
        /// <returns>String Value associated via a <see cref="StringValueAttribute"/> attribute, or null if not found.</returns>
        public static string GetStringValue(Enum value)
        {
            string output = null;
            Type type = value.GetType();

            if (_stringValues.ContainsKey(value))
                output = (_stringValues[value] as StringValueAttribute).Value;
            else 
            {
                //Look for our 'StringValueAttribute' in the field's custom attributes
                FieldInfo fi = type.GetField(value.ToString());
                StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof (StringValueAttribute), false) as StringValueAttribute[];
                if (attrs.Length > 0)
                {
                    _stringValues.Add(value, attrs[0]);
                    output = attrs[0].Value;
                }

            }
            return output;

        }

        /// <summary>
        /// Parses the supplied enum and string value to find an associated enum value (case sensitive).
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="stringValue">String value.</param>
        /// <returns>Enum value associated with the string value, or null if not found.</returns>
        public static object Parse(Type type, string stringValue)
        {
            return Parse(type, stringValue, false);
        }

        /// <summary>
        /// Parses the supplied enum and string value to find an associated enum value.
        /// </summary>
        /// <param name="type">Type.</param>
        /// <param name="stringValue">String value.</param>
        /// <param name="ignoreCase">Denotes whether to conduct a case-insensitive match on the supplied string value</param>
        /// <returns>Enum value associated with the string value, or null if not found.</returns>
        public static object Parse(Type type, string stringValue, bool ignoreCase)
        {
            object output = null;
            string enumStringValue = null;

            if (!type.IsEnum)
                throw new ArgumentException(String.Format("Supplied type must be an Enum.  Type was {0}", type.ToString()));

            //Look for our string value associated with fields in this enum
            foreach (FieldInfo fi in type.GetFields())
            {
                //Check for our custom attribute
                StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof (StringValueAttribute), false) as StringValueAttribute[];
                if (attrs.Length > 0)
                    enumStringValue = attrs[0].Value;

                //Check for equality then select actual enum value.
                if (string.Compare(enumStringValue, stringValue, ignoreCase) == 0)
                {
                    output = Enum.Parse(type, fi.Name);
                    break;
                }
            }

            return output;
        }

        /// <summary>
        /// Return the existence of the given string value within the enum.
        /// </summary>
        /// <param name="stringValue">String value.</param>
        /// <param name="enumType">Type of enum</param>
        /// <returns>Existence of the string value</returns>
        public static bool IsStringDefined(Type enumType, string stringValue)
        {
            return Parse(enumType, stringValue) != null;
        }

        /// <summary>
        /// Return the existence of the given string value within the enum.
        /// </summary>
        /// <param name="stringValue">String value.</param>
        /// <param name="enumType">Type of enum</param>
        /// <param name="ignoreCase">Denotes whether to conduct a case-insensitive match on the supplied string value</param>
        /// <returns>Existence of the string value</returns>
        public static bool IsStringDefined(Type enumType, string stringValue, bool ignoreCase)
        {
            return Parse(enumType, stringValue, ignoreCase) != null;
        }

        #endregion
    }

    #endregion

    #region Class StringValueAttribute

    /// <summary>
    /// Simple attribute class for storing String Values
    /// </summary>
    public class StringValueAttribute : Attribute
    {
        private string _value;

        /// <summary>
        /// Creates a new <see cref="StringValueAttribute"/> instance.
        /// </summary>
        /// <param name="value">Value.</param>
        public StringValueAttribute(string value)
        {
            _value = value;
        }

        /// <summary>
        /// Gets the value.
        /// </summary>
        /// <value></value>
        public string Value
        {
            get { return _value; }
        }
    }

    #endregion
}

回答by Michael Damatov

.NET 3.5 makes it simple by using extension methods:

.NET 3.5 通过使用扩展方法使其变得简单:

enum Color {Red, Green, Blue}

Can be iterated with

可以迭代

Enum.GetValues(typeof(Color)).Cast<Color>()

or define a new static generic method:

或者定义一个新的静态泛型方法:

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

Keep in mind that iterating with the Enum.GetValues() method uses reflection and thus has performance penalties.

请记住,使用 Enum.GetValues() 方法进行迭代会使用反射,因此会降低性能。