是否有任何好的解决方案来表示参数化枚举C# 3.0
?我正在寻找像OCaml或Haxe这样的东西。我现在只能想到具有简单枚举字段以便于切换的类层次结构,也许有更好的想法?
请参阅下面其中一个回复中的 Ocaml 示例,以下是 Haxe 代码:
enum Tree {
Node(left: Tree, right: Tree);
Leaf(val: Int);
}
不熟悉 OCaml 或 Haxe,也不够聪明,无法理解其他解释,我去查阅了Haxe 枚举文档——底部的“枚举类型参数”位似乎是相关部分。
基于此,我的理解如下:
“正常”枚举基本上是一个值,仅限于您在枚举定义中定义的内容。C# 示例:
enum Color{ Red, Green, Yellow, Blue };
Color c = Color.Red;
c
可以是Red
, Green
, Yellow
, 或Blue
, 但没有别的。
在 Haxe 中,您可以将复杂类型添加到枚举,从他们的页面中设计的示例:
enum Cell<T>{
empty;
cons( item : T, next : Cell<T> )
}
Cell<int> c = <I don't know>;
这似乎意味着它c
被限制为文字值empty
(如我们老式的 C# 枚举),或者它也可以是复杂类型cons(item, next)
,其中item
是 aT
和next
是 a Cell<T>
。
从未使用过它,它看起来可能会生成一些匿名类型(就像 C# 编译器在你这样做时所做的那样new { Name='Joe'}
。
每当你“访问”枚举值时,你必须声明item
并且next
当你这样做时,看起来他们绑定到临时局部变量。
Haxe 示例 - 您可以看到 'next' 被用作临时局部变量以从匿名 cons 结构中提取数据:
switch( c ) {
case empty : 0;
case cons(item,next): 1 + cell_length(next);
}
老实说,当我“点击”它似乎在做什么时,这让我大吃一惊。它看起来非常强大,我明白您为什么要在 C# 中寻找类似的功能。
C# 枚举与最初复制它们的 C/++ 枚举几乎相同。这基本上是一种很好的说法#define Red 1
,因此当您传递Color
对象时,编译器可以使用整数而不是字符串进行比较和存储。
我在 C# 中这样做的目的是使用泛型和接口。像这样的东西:
public interface ICell<T> {
T Item{ get; set; }
ICell<T>{ get; set; }
}
class Cons<T> : ICell<T> {
public T Item{ get; set; } /* C#3 auto-backed property */
public Cell<T> Next{ get; set; }
}
class EmptyCell<T> : ICell<T>{
public T Item{ get{ return default(T); set{ /* do nothing */ }; }
public ICell<T> Next{ get{ return null }; set{ /* do nothing */; }
}
然后你可以有一个List<ICell<T>>
包含项目和下一个单元格的,你可以EmptyCell
在最后插入(或者只是将Next
引用显式设置为空)。优点是因为EmptyCell
不包含成员变量,所以它不需要任何存储空间(如empty
Haxe 中的),而Cons
单元格则需要。
编译器还可以内联/优化其中的方法,EmptyCell
因为它们什么都不做,因此与仅将Cons
其成员数据设置为 null 相比,速度可能会有所提高。
我真的不知道。我欢迎任何其他可能的解决方案,因为我对我的解决方案并不特别自豪:-)
使用具有静态属性的类来表示枚举值。您可以选择使用私有构造函数来强制对类的所有引用都通过静态属性。
看看System.Drawing.Color
课堂。它使用这种方法。
C#(据我所知,一般是 .NET 框架)不像 Java 那样支持参数化枚举。话虽如此,您可能想查看属性。Java 枚举能够实现的一些功能在某种程度上可以通过属性实现。
仅仅为此使用一个类有什么问题?它很丑陋,但在 Java 人员获得语言集成 Enum 支持之前,他们就是这样做的!