如何枚举一个枚举 今天药忘吃喽~ 2024-03-31 17:45 114阅读 0赞 ## 问题描述: ## 如何在 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.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 values = new List(); 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(); } } `我正在使用 .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); } } `枚举一个字符串,不要忘记将这些东西转换回枚举值,以便枚举可以枚举。` `我从您的编辑中看到您想要实际操作枚举本身,上面的代码解决了您的原始帖子。` `原文链接:https://www.huntsbot.com/qa/aL7l/how-to-enumerate-an-enum?lang=zh_CN` > huntsbot.com – 高效赚钱,自由工作
相关 如何枚举一个枚举 问题描述: 如何在 C\ 中枚举 enum? 例如,以下代码无法编译: public enum Suit { Spa 今天药忘吃喽~/ 2024年03月31日 17:45/ 0 赞/ 115 阅读
相关 【枚举】信息类枚举 > `前言` 比如用户信息里面有个等级,12345。 通常,我们是建一个枚举类。 替代方法: 在实体类下添加自定义获取名称的方法。 好处:如果项目服务很多,方 拼搏现实的明天。/ 2022年12月24日 01:54/ 0 赞/ 257 阅读
相关 枚举 include <stdio.h> / 枚举 1, 什么是枚举 把一个事物所有可能的取值一一列举出来 2, 枚举的优缺点 冷不防/ 2022年10月02日 05:45/ 0 赞/ 178 阅读
相关 枚举 在学C++和做一些实践的时候发现,枚举类型有时候是必要的。 有时我们希望某些常量只在类中有效。由于\define定义的宏常量是全局的,不能达到目的,于是想当然地觉得应该用co 骑猪看日落/ 2022年08月27日 10:55/ 0 赞/ 252 阅读
相关 枚举 当定义一个枚举时,编译器就会创建一个扩展java.lang.Enum类的类定义。这个类是java.lang.Object的一个直接后代。但与普通类不同的是,枚举具有以下属性: 谁践踏了优雅/ 2022年06月10日 08:23/ 0 赞/ 273 阅读
相关 枚举 在第一次学习面向对象编程时,我记得最深的一句话就是“万物皆对象”。于是我一直秉承着这个思想努力的学习着JAVA,直到学习到枚举(Enum)时,看着它颇为奇怪的语法……我一直 Myth丶恋晨/ 2022年04月23日 08:34/ 0 赞/ 290 阅读
相关 枚举 题目:有3个方格,每个方格里面都有一个整数a1,a2,a3。已知0 <= a1, a2, a3 <= n,而且a1 + a2是2的倍数,a2 + a3是3的倍数, a1 + a 客官°小女子只卖身不卖艺/ 2022年04月06日 04:22/ 0 赞/ 248 阅读
相关 枚举 JDK1.5之前需要自定义枚举类 JDK 1.5 新增的 enum 关键字用于定义枚举类 若枚举只有一个成员, 则可以作为一种单例模式的实现方式 枚举类对象的属性 亦凉/ 2022年03月22日 02:54/ 0 赞/ 316 阅读
相关 枚举 枚举 什么是枚举? 枚举指的是在一定范围内取值,这个值必须是枚举类型中的任意一个,而且只能够取其中的一个 枚举的特点: 1.枚举的本质就是一个Java类 叁歲伎倆/ 2022年03月18日 01:28/ 0 赞/ 369 阅读
还没有评论,来说两句吧...