在 C# 中表示参数化枚举的最佳方式?
在 C# 3.0 中是否有任何好的解决方案来表示参数化枚举? 我正在寻找类似 OCaml 或 Haxe 有。 我现在只能想到带有简单枚举字段的类层次结构以便于切换,也许有更好的想法?
请参阅以下回复之一中的 Ocaml 示例,Haxe 代码如下:
enum Tree {
Node(left: Tree, right: Tree);
Leaf(val: Int);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
仅使用类来实现此目的有什么问题吗? 它很难看,但这就是 Java 人所做的,直到他们有了语言集成的 Enum 支持!
What's wrong with just using a class for this? Its ugly, but thats how the Java people did it until they had language integrated Enum support!
C#(据我所知,通常是 .NET 框架)不像 Java 那样支持参数化枚举。 话虽如此,您可能想查看属性。 Java 枚举所具有的一些功能在某种程度上可以通过属性来实现。
C# (the .NET framework in general, as far as I know) doesn't support parametrized enums like Java does. That being said, you might want to look at Attributes. Some of the features that Java enums are capable of are somewhat doable through Attributes.
使用具有静态属性的类来表示枚举值。 您可以选择使用私有构造函数来强制对该类的所有引用都通过静态属性。
看一下
System.Drawing.Color
类。 它使用这种方法。Use a class that with static properties to represent the enumeration values. You can, optionally, use a private constructor to force all references to the class to go through a static property.
Take a look at the
System.Drawing.Color
class. It uses this approach.由于不熟悉 OCaml 或 Haxe,也没有足够聪明来理解其他解释,我去查找了 Haxe 枚举文档 - 底部的“枚举类型参数”位似乎是相关部分。
我的理解如下:
“正常”枚举基本上是一个仅限于您在枚举定义中定义的内容的值。 C# 示例:
c
可以是Red
、Green
、Yellow
或Blue
, 但没有别的。在 Haxe 中,您可以向枚举添加复杂类型,来自其页面的设计示例:
似乎的意思是
c
仅限于文字值空
(就像我们老式的 C# 枚举),或者它也可以是复杂类型cons(item, next)
,其中item
是一个T
和next
是Cell
。从未使用过它,看起来它可能会生成一些匿名类型(就像 C# 编译器在执行
new { Name='Joe'}
时所做的那样。每当您“访问”枚举值时,您都必须声明
item
和next
,并且看起来它们绑定到临时局部变量。Haxe 示例 - 您可以看到“next”被用作临时局部变量,以从匿名 cons 结构中提取数据:
说实话,当我“单击”它似乎正在执行的操作时,这让我大吃一惊。 它看起来非常强大,我明白为什么您会在 C# 中寻找类似的功能。
C# 枚举与最初复制它们的 C/++ 枚举几乎相同。 这基本上是
#define Red 1
的一种很好的表达方式,因此当您传递Color
对象时,编译器可以使用整数而不是字符串进行比较和存储。我在 C# 中尝试这样做的方法是使用泛型和接口。 像这样的事情:
然后你可以有一个
List>
,其中包含项目和下一个单元格,并且你可以在末尾插入EmptyCell
(或者只是将Next
引用显式设置为 null)。优点是,由于
EmptyCell
不包含任何成员变量,因此不需要任何存储空间(如 Haxe 中的empty
),而缺点 单元格会。
编译器还可能内联/优化
EmptyCell
中的方法,因为它们不执行任何操作,因此与仅将Cons
的成员数据设置为 null 相比,速度可能会有所提高。我真的不知道。 我欢迎任何其他可能的解决方案,因为我并不为我的解决方案感到特别自豪:-)
Not being familiar with OCaml or Haxe, and not being clever enough to understand the other explanations, I went and looked up the Haxe enum documentation - the 'Enum Type Parameters' bit at the bottom seems to be the relevant part.
My understanding based on that is as follows:
A 'normal' enum is basically a value which is restricted to the things that you have defined in your enum definition. C# Example:
c
can either beRed
,Green
,Yellow
, orBlue
, but nothing else.In Haxe, you can add complex types to enums, Contrived example from their page:
What this appears to mean is that
c
is restricted to either being the literal valueempty
(like our old fashioned C# enums), or it can also be a complex typecons(item, next)
, whereitem
is aT
andnext
is aCell<T>
.Not having ever used this it looks like it is probably generating some anonymous types (like how the C# compiler does when you do
new { Name='Joe'}
.Whenever you 'access' the enum value, you have to declare
item
andnext
when you do so, and it looks like they get bound to temporary local variables.Haxe example - You can see 'next' being used as a temporary local variable to pull data out of the anonymous cons structure:
To be honest, this blew my mind when I 'clicked' onto what it seemed to be doing. It seems incredibly powerful, and I can see why you'd be looking for a similar feature in C#.
C# enums are pretty much the same as C/++ enums from which they were originally copied. It's basically a nice way of saying
#define Red 1
so the compiler can do comparisons and storage with integers instead of strings when you are passingColor
objects around.My stab at doing this in C# would be to use generics and interfaces. Something like this:
Then you could have a
List<ICell<T>>
which would contain items and next cell, and you could insertEmptyCell
at the end (or just have theNext
reference explicitly set to null).The advantages would be that because
EmptyCell
contains no member variables, it wouldn't require any storage space (like theempty
in Haxe), whereas aCons
cell would.The compiler may also inline / optimize out the methods in
EmptyCell
as they do nothing, so there may be a speed increase over just having aCons
with it's member data set to null.I don't really know. I'd welcome any other possible solutions as I'm not particularly proud of my one :-)