在C# 3.0
中是否有任何好的解决方案来表示参数化的枚举?我正在寻找像OCaml或Haxe之类的东西。我只能用一个简单的枚举字段来考虑类层次结构,以便现在轻松切换,也许有更好的想法?在C#中表示参数化枚举的最佳方式?
见Ocaml程序编写的一份答复下面的例子中,一个HAXE代码如下:
enum Tree {
Node(left: Tree, right: Tree);
Leaf(val: Int);
}
在C# 3.0
中是否有任何好的解决方案来表示参数化的枚举?我正在寻找像OCaml或Haxe之类的东西。我只能用一个简单的枚举字段来考虑类层次结构,以便现在轻松切换,也许有更好的想法?在C#中表示参数化枚举的最佳方式?
见Ocaml程序编写的一份答复下面的例子中,一个HAXE代码如下:
enum Tree {
Node(left: Tree, right: Tree);
Leaf(val: Int);
}
不熟悉OCaml或Haxe,也没有足够聪明来理解其他解释,于是我去查找Haxe enum documentation - 底部的'Enum Type Parameters'位似乎是相关部分。基于该
我的理解如下:
“正常”枚举基本上被限制为您在枚举定义已定义的事物的价值。 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>
。
由于没有使用过这一点,看起来它可能产生一些匿名类型(比如当你做new { Name='Joe'}
C#编译器如何做。
每当你“访问”枚举值,你必须声明item
和next
时你这样做,它看起来像他们坐上开往暂时的局部变量
HAXE例子 - 你可以看到“下一步”被用作临时局部变量来提取数据进行匿名利弊结构:
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的速度增加。
我真的不知道。我会欢迎任何其他可能的解决方案,因为我并不特别为自己的解决方案感到骄傲:-)
谢谢,这正是我真正想到的,但您提供了一个非常详细的解释,说明它可以如何完成!也许没有比这更好的了... – 2008-09-16 08:12:28
C#(一般在.NET框架,据我所知)像Java那样不支持参数化的枚举。这就是说,你可能想看看属性。 Java枚举所具备的某些功能可通过属性进行某种操作。
如果我错了,请纠正我,但我认为Java枚举允许使用参数 - 但对于所有枚举构造而言都是相同的,而不是像OCaml那样每个构造都有唯一的参数列表。我需要ocaml的方式,所以属性在这里没有多大的帮助 - 但无论如何,谢谢! – 2008-09-15 21:07:15
为此仅使用一个类会出现什么问题?它的丑陋,但那是Java人们如何做到这一点,直到他们的语言集成了Enum支持!
类的问题在于很难切换它们。给定一个枚举值,我想用一种快捷的方式来理解它是什么以及它是什么论点。我可以通过类层次结构和简单的枚举开关来实现,但这听起来不太优雅.. – 2008-09-15 21:19:54
使用类与静态属性来表示枚举值。您可以选择使用私有构造函数来强制对该类的所有引用通过静态属性。
看看System.Drawing.Color
课程。它使用这种方法。
对于我们这些不了解OCaml或haXe的人,您能否提供例子? – 2008-09-15 20:52:53