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
下一篇: 如何使用基础值定义一个枚举常量
