如何枚举一个枚举

时间: 2023-08-15 admin 互联网

如何枚举一个枚举

如何枚举一个枚举

问题描述:

如何在 C# 中枚举 enum?

例如,以下代码无法编译:

public enum Suit
{Spades,Hearts,Clubs,Diamonds
}public void EnumerateAllSuitsDemoMethod()
{foreach (Suit suit in Suit){DoSomething(suit);}
}

它给出了以下编译时错误:

“西装”是一种“类型”,但用作“变量”

它在第二个关键字 Suit 上失败。

解决方案1:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

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

注意:强制转换为 (Suit[]) 并不是绝对必要的,but it does make the code 0.5 ns faster。

如果枚举器列表中有重复值,这将不起作用。

我只想指出,不幸的是,这在 silverlight 中不起作用,因为 silverlight 库不包含 enum.GetValues。在这种情况下,您必须使用反射。

@Jessy 这确实适用于像 enum E {A = 0, B = 0} 这样的重复情况。 Enum.GetValues 导致返回两个值,尽管它们是相同的。 E.A == E.B 为真,因此没有区别。如果您想要单独的名称,那么您应该查找 Enum.GetNames。

然后,如果您的枚举中有重复项/同义词,并且您想要其他行为,您可以使用 Linq 的 Distinct 扩展(从 .NET 3.5 开始),所以 foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }。

我错误地尝试使用 var 作为类型。编译器会将变量设为 Object 而不是枚举。明确列出枚举类型。

解决方案2:

huntsbot.com – 高效赚钱,自由工作

在我看来,您真的想打印出每个枚举的名称,而不是值。在这种情况下,Enum.GetNames() 似乎是正确的方法。

public enum Suits
{Spades,Hearts,Clubs,Diamonds,NumSuits
}public void PrintAllSuits()
{foreach (string name in Enum.GetNames(typeof(Suits))){System.Console.WriteLine(name);}
}

顺便说一句,增加值并不是枚举枚举值的好方法。你应该这样做。

我会改用 Enum.GetValues(typeof(Suit))。

public enum Suits
{Spades,Hearts,Clubs,Diamonds,NumSuits
}public void PrintAllSuits()
{foreach (var suit in Enum.GetValues(typeof(Suits))){System.Console.WriteLine(suit.ToString());}
}

此处的 VB 语法:link

我对您的版本进行了以下小改动:Enum.GetValues(typeof(Suits)).OfType().ToArray()。在这种情况下,我可以迭代 Suits 枚举项的数组,而不是字符串。

@Barabas 为什么不只做 Suits suit in Enum.GetValues(typeof(Suits)) ?

解决方案3:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

我做了一些扩展以便于枚举使用。也许有人可以使用它…

public static class EnumExtensions
{/// /// Gets all items for an enum value./// /// /// The value./// public static IEnumerable GetAllItems(this Enum value){foreach (object item in Enum.GetValues(typeof(T))){yield return (T)item;}}/// /// Gets all items for an enum type./// /// /// The value./// public static IEnumerable GetAllItems() where T : struct{foreach (object item in Enum.GetValues(typeof(T))){yield return (T)item;}}/// /// Gets all combined items from an enum value./// /// /// The value./// /// /// Displays ValueA and ValueB./// /// EnumExample dummy = EnumExample.Combi;/// foreach (var item in dummy.GetAllSelectedItems())/// {///    Console.WriteLine(item);/// }/// /// public static IEnumerable GetAllSelectedItems(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;}}}/// /// Determines whether the enum value contains a specific value./// /// The value./// The request./// ///     true if value contains the specified value; otherwise, false./// /// /// /// EnumExample dummy = EnumExample.Combi;/// if (dummy.Contains(EnumExample.ValueA))/// {///     Console.WriteLine("dummy contains EnumExample.ValueA");/// }/// /// public static bool Contains(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;}
}

枚举本身必须用 FlagsAttribute 装饰:

[Flags]
public enum EnumExample
{ValueA = 1,ValueB = 2,ValueC = 4,ValueD = 8,Combi = ValueA | ValueB
}

用于第一种扩展方法的一个衬垫;它不再懒惰了。返回 Enum.GetValues(typeof(T)).Cast();

或者,您也可以使用 OfType:Enum.GetValues(typeof(T)).OfType()。太糟糕了,没有 GetValues() 的通用版本,那么它会更加光滑。

也许有人可以展示如何使用这些扩展?编译器不会在枚举 EnumExample 上显示扩展方法。

+1 可重用代码:示例 - 将这些扩展方法保存在库中并引用它 [Flags]public enum mytypes{name1, name2 };列表<字符串> myTypeNames = mytypes.GetAllItems();

从 C# 7.3 (Visual Studio 2017 ≥ v15.7) 开始,可以使用 where T: Enum

解决方案4:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

.NET 框架的某些版本不支持 Enum.GetValues。以下是来自 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;
}

与涉及 reflection 的任何代码一样,您应该采取措施确保它只运行一次并缓存结果。

为什么不在这里使用 yield 关键字来实例化一个列表呢?

或更短:return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast();

@nawfal:Linq 不可用 .Net CF 2.0。

解决方案5:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

使用 Cast:

var suits = Enum.GetValues(typeof(Suit)).Cast();

你去吧,IEnumerable。

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

这也适用于 from 子句和 foreach 标头声明符。

'cast' api 需要 System.Linq。我只是缺少演员。

解决方案6:

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

我认为这比其他建议更有效,因为每次循环时都不会调用 GetValues()。它也更简洁。如果 Suit 不是 enum,则会出现编译时错误,而不是运行时异常。

EnumLoop.ForEach((suit) => {DoSomethingWith(suit);
});

EnumLoop 有这个完全通用的定义:

class EnumLoop where Key : struct, IConvertible {static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key));static internal void ForEach(Action act) {for (int i = 0; i < arr.Length; i++) {act(arr[i]);}}
}

小心使用这样的泛型。如果您尝试将 EnumLoop 与某种非枚举类型一起使用,它会编译得很好,但会在运行时引发异常。

谢谢你。运行时异常实际上会与此页面上的其他答案一起发生......除了这个,因为我添加了“where Key : struct, IConvertible”,因此在大多数情况下都会出现编译时错误。

不,GetValues() 在 foreach 中只调用一次。

詹姆斯,我会劝阻你的课程,因为聪明写得很好,但在许多人将维护和更新的生产代码中,聪明是额外的工作。如果它节省了大量资金或将被大量使用——所以节省的资金很大,人们会熟悉它——这是值得的,但在大多数情况下,它会减慢人们阅读和更新代码的速度,并引入一个可能的未来的源错误。代码越少越好:) 复杂性越低越好。

@GrantM 为什么?这段代码既不复杂,也非常短。最重要的是,按照他的示例,编写一次类将允许使用更短的代码迭代。这非常干净,如果您无法更新该代码,则可能无法更新任何公司代码。

解决方案7:

huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。

您不会在 Silverlight 中获得 Enum.GetValues()。

Original Blog Post by Einar Ingebrigtsen:

public class EnumHelper
{public static T[] GetValues(){Type enumType = typeof(T);if (!enumType.IsEnum){throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");}List values = new List();var fields = from field in enumType.GetFields()where field.IsLiteralselect 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 values = new List();var fields = from field in enumType.GetFields()where field.IsLiteralselect field;foreach (FieldInfo field in fields){object value = field.GetValue(enumType);values.Add(value);}return values.ToArray();}
}

我正在使用 .NET framework 4.0 & silverlight enum.getvalues 工作,我使用的代码是 ---> enum.GetValues(typeof(enum))

从 C# 7.3 (Visual Studio 2017 ≥ v15.7) 开始,可以使用 where T: Enum

解决方案8:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

新的 .NET 5 解决方案:

.NET 5 引入了一个 new generic version for the GetValues 方法:

Suit[] suitValues = Enum.GetValues();

这是迄今为止最方便的方法。

foreach 循环中的用法:

foreach (Suit suit in Enum.GetValues())
{}

并获取枚举名称:

string[] suitNames = Enum.GetNames();

解决方案9:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

我的解决方案适用于 .NET Compact Framework (3.5) 并支持在编译时进行类型检查:

public static List GetEnumValues() where T : new() {T valueType = new T();return typeof(T).GetFields().Select(fieldInfo => (T)fieldInfo.GetValue(valueType)).Distinct().ToList();
}public static List GetEnumNames() {return typeof (T).GetFields().Select(info => info.Name).Distinct().ToList();
}

如果有人知道如何摆脱 T valueType = new T(),我很乐意看到解决方案。

调用如下所示:

List result = Utils.GetEnumValues();

使用 T valueType = default(T) 怎么样?

太好了,我什至不知道那个关键字。总是很高兴学习新东西。谢谢!它总是返回对同一个对象的引用,还是每次调用默认语句时都会创建一个新实例?到目前为止,我还没有在网上找到任何关于此的内容,但如果它每次都创建一个新实例,那么它有点违背了我正在寻找的目的(有一个单行 ^^)。

这不会为枚举的每次迭代创建一个新实例吗?

-1 表示“在编译时支持类型检查:”。什么类型检查?这适用于任何 new() T。此外,您根本不需要 new T(),您可以只选择静态字段并执行 .GetValue(null)。见奥布里的回答。

从 C# 7.3 (Visual Studio 2017 ≥ v15.7) 开始,可以使用 where T: Enum

解决方案10:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

我认为你可以使用

Enum.GetNames(Suit)

解决方案11:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

public void PrintAllSuits()
{foreach(string suit in Enum.GetNames(typeof(Suits))){Console.WriteLine(suit);}
}

枚举一个字符串,不要忘记将这些东西转换回枚举值,以便枚举可以枚举。

我从您的编辑中看到您想要实际操作枚举本身,上面的代码解决了您的原始帖子。

原文链接:=zh_CN

huntsbot.com – 高效赚钱,自由工作