How to define an enum constant using the underlying value
What is the F# equivalent of this C#:
const MyEnum None = (MyEnum)1;
This does not work:
[<Literal>]
let None : MyEnum = enum 1 //ERROR: not a valid constant expression
although, curiously, it's okay in an attribute constructor:
[<MyAttribute(enum 1)>]
type T = class end
The discrepancy seems odd.
UPDATE
This is fixed in v3.1 and works as expected.
I believe the observed compiler behavior is intentional and completely in line with restrictions for values having [<Literal>]
attribute defined by F# Language Spec $10.2.2:
The right-hand side expression must be a literal constant expression that is made up of either:
Consider
type MyEnum =
| Case1 = 1
| Case2 = 2
then
[<Literal>]
let Valid: MyEnum = MyEnum.Case1 // Literal enumeration case on the right
will happily compile, but
[<Literal>]
let Invalid: MyEnum = enum<MyEnum>(1) // Expression on the right
// generating constant value, which
// potentially might be completely off
// legit MyEnum cases
will not, although outside of [<Literal>]
context both statements will compile into absolutely identical IL.
Assuming that [<Literal>]
attribute is the only F# way of making C# const
equivalent the only option for defining enumeration literal value would be using a literal enumeration case of proper type on the right side of let
.
The discrepancy is caused by the fact that C# (MyEnum)0
is indeed a literal, but F# enum
is a function of type int32 -> 'T
.
I believe it would not be difficult for F# team to add special processing for this construct, but unfortunately it is not there yet.
Nevertheless, there is one way to accomplish what you need, but only for 0
value:
type MyEnum =
| None = 0
| Foo = 1
[<Literal>]
let X = MyEnum()
链接地址: http://www.djcxy.com/p/11762.html
上一篇: ComboBox SelectionChangeCommitted事件不适用于AutoComplete
下一篇: 如何使用基础值定义一个枚举常量