在C#中表示参数化枚举的最佳方法?

时间:2008-09-15 20:50:38

标签: c# enums ocaml haxe

C# 3.0中表示参数化枚举是否有任何好的解决方案?我正在寻找OCamlHaxe之类的内容。我只能用简单的枚举字段来考虑类层次结构,以便现在轻松切换,也许有更好的想法?

请参阅下面的一个回复中的Ocaml示例,以下是Haxe代码:

enum Tree {
   Node(left: Tree, right: Tree);
   Leaf(val: Int);
}

4 个答案:

答案 0 :(得分:7)

不熟悉OCaml或Haxe,并且不够聪明地理解其他解释,我去查找Haxe enum documentation - 底部的'枚举类型参数'位似乎是相关部分

基于此的理解如下:

“普通”枚举基本上是一个值,它仅限于您在枚举定义中定义的内容。 C#示例:

enum Color{ Red, Green, Yellow, Blue };
Color c = Color.Red;

c可以是RedGreenYellowBlue,但不能提供任何其他内容。

在Haxe中,您可以在枚举中添加复杂类型,从其页面中添加Contrived示例:

enum Cell<T>{ 
  empty; 
  cons( item : T, next : Cell<T> )
}

Cell<int> c = <I don't know>;

这个出现意味着c被限制为文字值empty(就像我们过时的C#枚举一样),或者它也可以是复杂类型cons(item, next),其中itemTnextCell<T>

从未使用过它,看起来它可能会产生一些匿名类型(比如当你执行new { Name='Joe'}时C#编译器的工作方式。) 每当您“访问”枚举值时,您必须在执行此操作时声明itemnext,并且看起来它们会绑定到临时局部变量。

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不包含任何成员变量,所以不需要任何存储空间(如Haxe中的empty),而Cons单元格则需要。 编译器也可以内联/优化EmptyCell中的方法,因为它们什么也不做,因此可能会有一个速度提高,而不仅仅是Cons,其成员数据设置为null。

我真的不知道。我欢迎任何其他可能的解决方案,因为我并不特别为我的解决方案感到骄傲: - )

答案 1 :(得分:1)

使用带有静态属性的来表示枚举值。您可以选择使用私有构造函数强制对类的所有引用都通过静态属性。

看一下System.Drawing.Color课程。它使用这种方法。

答案 2 :(得分:0)

C#(据我所知,一般来说,.NET框架)不支持像Java那样的参数化枚举。话虽这么说,你可能想看看属性。 Java枚举所具备的一些功能在属性方面有些可行。

答案 3 :(得分:0)

为此使用课程有什么问题?它的丑陋,但这就是Java人们在语言集成了Enum支持之前是如何做到的!