観察されたコンパイラの動作は意図的であり、 F# 言語仕様 $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# と同等にする唯一の F# の方法が属性であると仮定するとconst
、 の右側で適切な型のリテラル列挙ケースを使用することになりますlet
。