我相信观察到的编译器行为是有意的,并且完全符合对具有F# Language Spec $10.2.2[<Literal>]
定义的属性的值的限制:
右边的表达式必须是一个文字常量表达式,由以下任一组成:
- 一个简单的常量表达式,除了 ()、本机整数文字、无符号本机整数文字、字节数组文字、BigInteger 文字和用户定义的数字文字。—或者—</li>
- 对另一个字面量的引用
考虑
type MyEnum =
| Case1 = 1
| Case2 = 2
然后
[<Literal>]
let Valid: MyEnum = MyEnum.Case1 // Literal enumeration case on the right
会很高兴地编译,但是
[<Literal>]
let Invalid: MyEnum = enum<MyEnum>(1) // Expression on the right
// generating constant value, which
// potentially might be completely off
// legit MyEnum cases
不会,尽管在[<Literal>]
上下文之外,这两个语句都将编译成完全相同的 IL。
假设该[<Literal>]
属性是使 C#const
等效的唯一 F# 方法,定义枚举文字值的唯一选项将是在let
.