如何枚举一个枚举
问题描述:
如何在 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 – 高效赚钱,自由工作
还没有评论,来说两句吧...