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

标签 c# enums ocaml haxe

C# 3.0 中是否有任何好的解决方案来表示参数化枚举?我正在寻找类似 OCaml 的东西或 Haxe有。我现在只能想到具有简单枚举字段的类层次结构,以便于切换,也许有更好的想法?

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

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

最佳答案

不熟悉 OCaml 或 Haxe,也没有足够聪明地理解其他解释,我去查找了 Haxe enum documentation - 底部的“枚举类型参数”位似乎是相关部分。

基于此我的理解如下:

“普通”枚举基本上是一个值,它仅限于您在枚举定义中定义的内容。 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) , 其中itemTnextCell<T> .

从来没有使用过它,看起来它可能会生成一些匿名类型(就像 C# 编译器在您执行 new { Name='Joe'} 时的处理方式。
每当您“访问”枚举值时,都必须声明 itemnext当您这样做时,看起来它们会绑定(bind)到临时局部变量。

Haxe 示例 - 您可以看到“next”被用作临时局部变量以从匿名 cons 结构中提取数据:

switch( c ) {
  case empty : 0;
  case cons(item,next): 1 + cell_length(next);
}

老实说,当我“点击”它似乎在做什么时,这让我大吃一惊。它看起来非常强大,我明白您为什么要在 C# 中寻找类似的功能。

C# 枚举与最初复制它们的 C/++ 枚举几乎相同。这基本上是一种很好的说法 #define Red 1因此当您传递 Color 时,编译器可以使用整数而不是字符串进行比较和存储。周围的物体。

我尝试在 C# 中执行此操作是使用泛型和接口(interface)。像这样:

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 来提高速度将其成员数据设置为空。

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

关于c# - 在 C# 中表示参数化枚举的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66819/

相关文章:

ios - 更新/更改 Swift 中枚举的 rawValue

profiling - 使用分析信息编译的 OCaml 二进制文件

string - 如何从 OCaml 中的字符串中去除空格?

c# - 在 WPF 应用程序中应用 MVVM 模式

c# - C#面板/图片框的问题

swift - 需要了解ENUM以便在SpriteKit中进行联系

c - 使用 C 进行数字到字符串的映射

ocaml - 引用顶层文件中定义的模块类型

c# - 实例化时的 StackOverflow 错误

c# - 从两个不同的词典中获取相同的键