2010-03-08 44 views
17

在C#可以定義一種類型的構件常數是這樣的:如何在F#中定義類型成員常量?

class Foo { public const int Bar = 600; } 

的IL看起來像這樣。

.field public static literal int32 Bar = int32(600) 

如何在Visual F#/ FSharp中執行相同操作?

我想這無濟於事:

[<Sealed>] 
type Foo() = 

    [<Literal>] 
    let Bar = 600 
+0

我問這個問題 - http://stackoverflow.com/questions/1834923/f-public-literal-和克里斯史密斯表示這是不可能的。 – Daniel 2010-03-09 04:08:07

回答

0

我不知道這是可能的。事實上,我甚至不認爲你可以創建不可變的公共字段,更不用說常量。

+0

我相信你可以在使用'new()'編寫的構造函數中使用'val'聲明和顯式初始化來創建公共不可變字段,但是這對常量不起作用,因爲'val'字段在構造函數中初始化。 – 2010-03-08 19:04:36

+0

@Tomas--我認爲你會發現你的建議實際上會導致一個屬性被定義,而不是一個字段。然而,使用'val mutable'會導致可變域。 – kvb 2010-03-08 19:11:48

+0

你說得對。 public'val'產生一個帶有私有字段的屬性(動機是禁止類的可能的C#用戶修改應該是不可變的字段)。 – 2010-03-08 19:23:56

18

我用F#編譯器做了一些實驗,下面是我的一些觀察。如果你想創建IL文字,那麼你需要將標記爲Literal的值放入模塊中。例如像這樣:

module Constants = 
    [<Literal>] 
    let Num = 1 

作爲一個側面說明,我沒有通過F#規範了快速搜索,似乎文字可進行模式匹配非常有用的,因爲你可以用它們作爲一種模式(如只要他們開始以一個大寫字母):

open Constants 
match 1 with 
| Num -> "1" 
| _ -> "other" 

現在的問題是,爲什麼Literal不表現爲,當你把它放在一個類型聲明中你所期望的。我認爲原因在於F#類型聲明中的let聲明不能公開,只能在類/類中看到。我相信,當你使用C#和F#內聯字面值時,這也是在類型聲明中完成的。但由於文字不能公開,因此沒有理由生成IL字段,因爲沒有人能訪問它。

+0

在C#中,文字將在字節碼中內聯,但常量字段仍然存在,其他類型將被使用。 – zproxy 2010-03-09 10:08:01

+0

是 - 在F#中,如果文字是公開的(例如,在模塊中)並且可以被某人使用,則會生成'field';如果它只在類內部可見,則沒有意義生成字節碼,因爲其他類型無法使用它。 – 2010-03-09 12:49:46

相關問題