【问题标题】:Getting an Enum member by its index (not the value assigned to it) in c#在 C# 中通过索引(而不是分配给它的值)获取枚举成员
【发布时间】:2021-05-16 14:55:21
【问题描述】:

JavaScript 世界中,您可以根据它在对象中的索引获得一个枚举值(不是分配给枚举成员的值,而是该枚举的第 n 个成员):

const myEnum = {
    Hello: 1,
    Bye: 2,
    Greeting: 3
}
const value = myEnum[Object.keys(myEnum)[0]];
console.log(value) // it returns 1

我想知道C# 中是否也有这种行为。

我试图在C# 中找到枚举的第 n 个成员,其中的值都不同,并且它们没有顺序(这正是我希望它们成为的样子)。

更新

enum CSharpEnum {
    SomeValue = 4,
    AnotherValue = 2,
    AndAnotherOne = 1
}

我从其他地方获得了一些索引(如 n),我想获得CSharpEnum 的第 n 个成员。一个例子:

var index = 2;
var member // a way to get the member and it should return 1 (AndAnotherOne)
// because it is the third member (0, 1, 2)

更新 2

看来我的问题还不够清楚,所以这里是 dotnetfiddle 游乐场的link。 在其中一个答案中有一个GetValues 方法,它列出了枚举值,但枚举成员在其中重新排列。 我在操场上有一个枚举,我想获得第三个 (0, 1, 2) 成员,例如 Want。有什么办法可以得到吗?

【问题讨论】:

  • 您的示例看起来不像是在显示您的意图?你到底想要什么?源代码中的出现顺序还是值的顺序?为了使您的意图明确,您可以提供所需结果的示例,其中源顺序是混合的(例如enum { XSecond = 3, Third = 9, First = 1} 我将X 放在第二个前面,所以它不会被误认为是字母顺序名称)
  • 我更新了帖子。 @grek40 我希望现在很清楚我在寻找什么。
  • 感谢您的澄清。 (据我所知)没有修改枚举没有可靠的方法。网络上的典型解决方案依赖于规范不保证的实现细节或使用显式注释。如果您想要一个不同于值或名称顺序的特定顺序,您应该使用所需的顺序显式注释枚举成员。
  • 没有可靠的方法可以做到这一点。对于当前版本的编译器,有多种方法可以获取 恰好可以工作 的枚举字段,但依赖它是愚蠢的。如果您使用 Roslyn 自己解析代码而不是检查类型,则可以在编译时使其可靠地工作,但这更多的是在代码生成器领域。 C# 枚举不像 JavaScript 那样(明确地)是有序的标签集合。

标签: c# enums enumerate


【解决方案1】:

带枚举

public enum Test
{
    hello,
    world
}

创建一个数组

var enums = (Test[])Enum.GetValues(typeof(Test));

现在它是可索引的。

【讨论】:

  • 是的,但顺序不对。它变成了这样:enumArray = [AndAnotherOne, AnotherValue, SomeValue]
【解决方案2】:

给定

public enum myEnum
{
    Hello = 1,
    Bye = 2,
    Greeting = 3
}

Enum Class 有一个静态方法 GetValues(Type),它返回这个枚举值的数组 TEnum[]

myEnum[] enumArray = (myEnum[])Enum.GetValues(typeof(myEnum));
myEnum value = enumArray[i]; // { [0] = Hello, [1] = Bye, [3] = Greeting }

较新版本的框架具有通用重载(从 .NET Framework 5.0 开始?):

myEnum[] enumArray = Enum.GetValues<myEnum>();
myEnum value = enumArray[i];

更新

枚举类型的目的是提供一组具有基础整数数字类型的命名常量。这些常量没有索引并且没有定义特定的顺序。如果您想让它们被索引,请将它们插入到数组中

enum myEnum {
    SomeValue = 4,
    AnotherValue = 2,
    AndAnotherOne = 1
}
static readonly myEnum[] enumArray = new[] {
    myEnum.SomeValue,
    myEnum.AnotherValue,
    myEnum.AndAnotherOne
};
myEnum value = enumArray[2]; // --> myEnum.AndAnotherOne

另见:Enumeration types (C# reference)

【讨论】:

  • EnumsNet 会在 .NET 6 中过时吗?
  • 我从未使用过它,但根据Enums.NET 的Read.me 文件,它提供的功能远不止这个通用的GetValues
  • 问题是值被重新排列成正确的顺序enumArray = [AndAnotherOne, AnotherValue, SomeValue]
  • 它们会根据它们的数值重新排列。但在您的示例中,它们保持原始顺序{ [0] = Hello, [1] = Bye, [3] = Greeting },其中[n] 是数组索引。如果您想要枚举的数值,可以使用int i = (int)enumValue; 将其转换为int
  • 您愿意看看我添加到问题中的操场吗?我已经更新了这个问题。也许现在更清楚我在寻找什么?!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多