2010-03-08 108 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

相关问题