在 C# 中使用枚举作为数组索引
我想做与这个问题相同的事情,即:
enum DaysOfTheWeek {Sunday=0, Monday, Tuesday...};
string[] message_array = new string[number_of_items_at_enum];
...
Console.Write(custom_array[(int)DaysOfTheWeek.Sunday]);
然而,我宁愿有一些不可或缺的东西,而不是编写这个容易出错的代码。 C# 中是否有内置模块可以实现此目的?
I want to do the same as in this question, that is:
enum DaysOfTheWeek {Sunday=0, Monday, Tuesday...};
string[] message_array = new string[number_of_items_at_enum];
...
Console.Write(custom_array[(int)DaysOfTheWeek.Sunday]);
however, I would rather have something integral to so, rather than write this error prone code. Is there a built in module in C# that does just this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
如果您本质上需要的是一个映射,但不想产生与字典查找相关的性能开销,这可能会起作用:
所以在您的情况下,您可以得出:
用法:
显然这个实现是由数组支持的,所以是不连续的像这样的枚举:
会导致内存使用过多。
如果您需要最大可能的性能,您可能希望使其不那么通用,并释放我必须用来编译和工作的所有通用枚举处理代码。 不过我没有对此进行基准测试,所以也许这没什么大不了的。
缓存 Keys 静态属性也可能有所帮助。
If all you need is essentially a map, but don't want to incur performance overhead associated with dictionary lookups, this might work:
So in your case you could derive:
Usage:
Obviously this implementation is backed by an array, so non-contiguous enums like this:
would result in excessive memory usage.
If you require maximum possible performance you might want to make it less generic and loose all generic enum handling code I had to use to get it to compile and work. I didn't benchmark this though, so maybe it's no big deal.
Caching the Keys static property might also help.
为了将来的参考,上述问题可以总结如下:
我来自 Delphi,您可以如下定义一个数组:
然后您可以使用 Min 和 Max 迭代该数组:
虽然这是一个相当人为的示例,但当您处理稍后在代码中的数组位置我只需键入 DaysOfTheWeekStrings[TDaysOfTheWeek.Monday] 即可。 这样做的好处是,我应该增加
TDaysOfTheWeek
的大小,然后我就不必记住数组的新大小等......但是回到 C# 世界。 我找到了这个示例 C# 枚举数组示例。For future reference the above problem can be summarized as follows:
I come from Delphi where you can define an array as follows:
Then you can iterate through the array using Min and Max:
Though this is quite a contrived example, when you are dealing with array positions later in the code I can just type
DaysOfTheWeekStrings[TDaysOfTheWeek.Monday]
. This has the advantage of the fact that I should theTDaysOfTheWeek
increase in size then I do not have to remember the new size of the array etc..... However back to the C# world. I have found this example C# Enum Array Example.我意识到这是一个老问题,但是有很多评论表明到目前为止所有解决方案都具有运行时检查以确保数据类型是枚举。 这是带有编译时检查的解决方案的完整解决方案(带有一些示例)(以及我的开发人员同事的一些评论和讨论)
编辑:
如果您使用 C# 7.3 或更高版本,请不要使用这个丑陋的解决方案。 请参阅 Ian Goldby 2018 年的回答。
I realize this is an old question, but there have been a number of comments about the fact that all solutions so far have run-time checks to ensure the data type is an enum. Here is a complete solution (with some examples) of a solution with compile time checks (as well as some comments and discussions from my fellow developers)
EDIT:
If you are using C# 7.3 or later, PLEASE don't use this ugly solution. See Ian Goldby's answer from 2018.
您始终可以进行一些额外的映射,以一致且定义的方式获取枚举值的数组索引:
尽可能具体。 有一天,有人会修改您的枚举,并且代码将失败,因为枚举的值被(错误)用作数组索引。
You can always do some extra mapping to get an array index of an enum value in a consistent and defined way:
Be as specific as you can. One day someone will modify your enum and the code will fail because the enum's value was (mis)used as an array index.
这是 @ian-goldby 的一个非常好的答案,但它没有解决 @zar-shardan 提出的问题,这是我自己遇到的问题。 下面是我对解决方案的看法,其中有一个用于转换 IEnumerable 的扩展类,下面是一个测试类:
这是扩展类:
这是我的测试:
It was a very good answer by @ian-goldby, but it didn't address the issue raised by @zar-shardan, which is an issue I hit myself. Below is my take on a solution, with a an extension class for converting an IEnumerable, and a test class below that:
Here's the extension class:
And here are my tests:
如果枚举项的值是连续的,则数组方法效果很好。 但是,无论如何,您都可以使用
Dictionary
(顺便说一句,性能较差)。If the values of your enum items are contigious, the array method works pretty well. However, in any case, you could use
Dictionary<DayOfTheWeek, string>
(which is less performant, by the way).从 C# 7.3 开始,可以使用
System.Enum
作为类型参数的约束。 因此,不再需要其他一些答案中的令人讨厌的黑客行为。这是一个非常简单的 ArrayByEum 类,它完全按照问题要求进行操作。
请注意,如果枚举值不连续,它将浪费空间,并且无法处理对于
int
来说太大的枚举值。 我确实说过这个例子很简单。用法:
Since C# 7.3 it has been possible to use
System.Enum
as a constraint on type parameters. So the nasty hacks in the some of the other answers are no longer required.Here's a very simple
ArrayByEum
class that does exactly what the question asked.Note that it will waste space if the enum values are non-contiguous, and won't cope with enum values that are too large for an
int
. I did say this example was very simple.Usage:
您可以创建一个类或结构来为您完成工作
编辑
由于缺乏更好的地方来放置它,我在下面发布了 Caster 类的通用版本。 不幸的是,它依赖于运行时检查来强制 TKey 作为枚举。
You could make a class or struct that could do the work for you
EDIT
For lack of a better place to put this, I am posting a generic version of the Caster class below. Unfortunately, it relies on runtime checks to enforce TKey as an enum.
在这里:
如果您确实需要长度,那么只需在结果上取 .Length :)
您可以通过以下方式获取值:
Here you go:
If you really need the length, then just take the .Length on the result :)
You can get values with:
枚举的紧凑形式用作索引并将任何类型分配给字典
和强类型。 在这种情况下,返回浮点值,但值可能是具有属性和方法等的复杂类实例:
Compact form of enum used as index and assigning whatever type to a Dictionary
and strongly typed. In this case float values are returned but values could be complex Class instances having properties and methods and more: