2014-04-16 23 views
1

我有一個具有枚舉屬性的類。要使用compact屬性語法,我必須用類型的值初始化它,例如。獲取F#中枚舉類型的第一個值

type Color = 
    | Blue= 0 
    | Green= 1 

type MyClass() = 
    member val Col = Color.Blue with get, set // <-- the problem 

不過,我不喜歡在那裏硬編碼Blue,並希望將其設置爲枚舉的第一個項目。

我已經能與此做:

member val Color = enum<Color>(unbox (Enum.GetValues(typeof<Color>).GetValue(0))) ... 

不用說了,我希望有一個更好的辦法要麼得到一個枚舉的第一個值,或初始化屬性!

+1

是'構件VAL列= Unchecked.defaultOf 以get,set'不希望的一些原因? – ildjarn

+0

@ildjarn看起來不錯,但它會產生奇怪的行爲!成員'Col'的推斷類型是'Color'(這是我想要的),但是當我評估MyClass().Col時,它產生'val it:Color = 0'(應該是'Blue')。 –

+0

這聽起來像一個FSI問題 - 代碼是否在運行時編譯和正確工作? – ildjarn

回答

2

鑑於你提到的兩種選擇,我相信你最好用Color.Blue。雖然支持枚舉的數字值完全是任意的,但顏色至少在應用程序中具有一些含義。如果你是直接設置值不舒服,因爲沒有相關的默認額外的意義,你可以隨時將其定義分別別的地方:

let standardUniformColor = Color.Blue 
//(...) 
type MyClass() = member val Col = standardUniformColor with get, set 
+0

我嘗試了類似的東西,並且遇到了這樣的問題:'standardUniformColor'必須在模塊中聲明,而我的類型是在名稱空間中聲明的。不過,我同意原則上,你對Color.Blue是一個改進。 –

+2

您可以將默認值設置爲您的類或其他類的靜態成員,或者將其添加到模塊中 - 無論您的程序是否有意義。 – duplode

+0

我發現人們可以在名稱空間中聲明一個模塊,所以我有'namespace Colors ... type Color = .. module Values = let defaultColor = Color.Blue'。然後我可以參考'Colors.Values.defaultColor'。我接受這個答案是最安全和最一般的解決方案。根據具體情況,可以使用這三種解決方案中的任何一種。 –

1

可以使用魔法enum功能,像這樣:

type Color = 
    | Blue= 0 
    | Green= 1 

type MyClass() = 
    member val Col : Color = enum 0 with get, set 

唯一的問題是你需要某個地方的類型註釋,以便編譯器知道要將哪個枚舉轉換爲。

注意:這假定枚舉的第一個值是0。

+0

對於類型註解,我可以使用'enum 0'或'enum 0:Color' –

+0

注意:這個答案假設enum的第一個值是0。我認爲對於完全一般的情況(例如'Blue = 10 |綠色= 20'),人們不得不用我冗長的表情。 (經實驗證實)。 –

+0

我已經決定@丹尼爾的建議是更好的(因爲我在評論中陳述的原因),所以已經將其改爲公認的答案。如果有人不同意,請隨時反對。 –

3

如果第一個成員是你的程序中顯著的話很有道理,使其明確。有兩個具有相同價值的成員是完全正確的。

type Color = 
    | Default = 0 
    | Blue = 0 
    | Green = 1 

type MyClass() = 
    member val Col = Color.Default with get, set 

由於枚舉平等取決於基礎值,這工作根據需要(即,打印"blue"):

let c = MyClass() 
match c.Col with 
| Color.Blue -> printfn "blue" 
| _ -> printfn "not blue" 
+0

我非常喜歡這個。我擔心的是,無論什麼時候優先級被用在'match'函數中,可能需要覆蓋'Default'的情況,但事實並非如此 - 它不會顯示任何警告。所以編譯器似乎使用數字值。唯一的限制是,如果更改枚舉值,那麼必須更改默認值,但這是全部在一個地方,所以應該很容易看到(....)。在答案中,我首先接受了硬編碼值'0',它用在與定義不同的地方。 –

+0

當我在程序中使用它時,遇到了一個問題,因爲我列舉了Enum.GetValues(typeof )中的c for en in類型,在這種情況下,編譯器使用符號而不是數字值,即。循環執行三次,'c'的值是'藍色','藍色','綠色'。我最終使用下面的@ duplode解決方案。 –