解决方案
由于不熟悉 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
是一个 T
和 next
是一个 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
引用显式设置为 null)。优点是因为 EmptyCell
不包含任何成员变量,它不需要任何存储空间(如 empty
在 Haxe 中),而 Cons
细胞会。
编译器还可以内联/优化中的方法 EmptyCell
因为他们什么都不做,所以速度可能会比仅仅拥有一个有所提高 Cons
其成员数据设置为空。
我真的不知道。我欢迎任何其他可能的解决方案,因为我并不为我的解决方案感到特别自豪:-)
其他提示
用一个 班级 用静态属性来表示枚举值。您可以选择使用私有构造函数来强制对该类的所有引用都通过静态属性。
看看 System.Drawing.Color
班级。它使用这种方法。
C#(据我所知,通常是 .NET 框架)不像 Java 那样支持参数化枚举。话虽如此,您可能想查看属性。Java 枚举所具有的一些功能在某种程度上可以通过属性来实现。
仅使用一个类来实现此目的有什么问题吗?它很难看,但这就是 Java 人所做的,直到他们有了语言集成的 Enum 支持!