2008-09-15 65 views
1

C# 3.0中是否有任何好的解決方案來表示參數化的枚舉?我正在尋找像OCamlHaxe之類的東西。我只能用一個簡單的枚舉字段來考慮類層次結構,以便現在輕鬆切換,也許有更好的想法?在C#中表示參數化枚舉的最佳方式?

見Ocaml程序編寫的一份答覆下面的例子中,一個HAXE代碼如下:

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

對於我們這些不瞭解OCaml或haXe的人,您能否提供例子? – 2008-09-15 20:52:53

回答

7

不熟悉OCaml或Haxe,也沒有足夠聰明來理解其他解釋,於是我去查找Haxe enum documentation - 底部的'Enum Type Parameters'位似乎是相關部分。基於該

我的理解如下:

「正常」枚舉基本上被限制爲您在枚舉定義已定義的事物的價值。 C#示例:

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

c可以是RedGreenYellow,或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>

由於沒有使用過這一點,看起來它可能產生一些匿名類型(比如當你做new { Name='Joe'} C#編譯器如何做。
每當你「訪問」枚舉值,你必須聲明itemnext時你這樣做,它看起來像他們坐上開往暫時的局部變量

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的速度增加。

我真的不知道。我會歡迎任何其他可能的解決方案,因爲我並不特別爲自己的解決方案感到驕傲:-)

+0

謝謝,這正是我真正想到的,但您提供了一個非常詳細的解釋,說明它可以如何完成!也許沒有比這更好的了... – 2008-09-16 08:12:28

0

C#(一般在.NET框架,據我所知)像Java那樣不支持參數化的枚舉。這就是說,你可能想看看屬性。 Java枚舉所具備的某些功能可通過屬性進行某種操作。

+0

如果我錯了,請糾正我,但我認爲Java枚舉允許使用參數 - 但對於所有枚舉構造而言都是相同的,而不是像OCaml那樣每個構造都有唯一的參數列表。我需要ocaml的方式,所以屬性在這裏沒有多大的幫助 - 但無論如何,謝謝! – 2008-09-15 21:07:15

0

爲此僅使用一個類會出現什麼問題?它的醜陋,但那是Java人們如何做到這一點,直到他們的語言集成了Enum支持!

+0

類的問題在於很難切換它們。給定一個枚舉值,我想用一種快捷的方式來理解它是什麼以及它是什麼論點。我可以通過類層次結構和簡單的枚舉開關來實現,但這聽起來不太優雅.. – 2008-09-15 21:19:54

1

使用與靜態屬性來表示枚舉值。您可以選擇使用私有構造函數來強制對該類的所有引用通過靜態屬性。

看看System.Drawing.Color課程。它使用這種方法。