如何在枚举中保留值类型

Nov*_*kov 9 enums f# attributes value-type

让我们看看下面这段代码,并假设两者MyAttributetest函数都无法更改.

type MyAttribute() =
    inherit Attribute()

    let mutable prop = null

    member this.Prop
        with get(): obj = prop
        and  set(value) = prop <- value


type MyEnum = 
    | A = 1
    | B = 2

[<My(Prop = MyEnum.B)>]
type MyClass = class
    end

let test () =
   let t = typeof<MyClass>
   let a = t.GetCustomAttributes(false).[0] :?> MyAttribute

   let e = a.Prop
   Convert.ToString(e, Globalization.CultureInfo.CurrentCulture)
Run Code Online (Sandbox Code Playgroud)

我希望test返回B但返回2.生成的IL代码显示有关枚举类型的信息丢失,传递给属性的值仅为2.

是否有任何方法(我想应该是某些属性)来保留属性值中的类型?什么更有趣的C#等效代码按预期工作

等价C#:

class MyAttribute : Attribute
{
    public object A { get; set; }
}

enum T { A,B,C }

[My(A = T.A)]
class MyClass
{ }

var a = typeof(MyClass).GetCustomAttributes(false)[0] as MyAttribute;

Convert.ToString(a.A, System.Globalization.CultureInfo.CurrentCulture)
Run Code Online (Sandbox Code Playgroud)

Col*_*ull 1

我猜测,我对编译器内部结构的了解实际上非常有限,但我想这与类型推断有关。int <-> Enum 之间存在等价关系,我怀疑类型推断正在将其减少到可能的最低类型,在本例中为 int。您可以通过执行以下操作来修复此问题

open System

type MyAttribute() =
    inherit Attribute()

    let mutable prop = null

    member this.Prop
        with get(): obj = prop
        and  set(value) = prop <- value


type MyEnum = 
    | A = 1
    | B = 2

[<My(Prop = MyEnum.B)>]
type MyClass = class
    end

let test () =
   let t = typeof<MyClass>
   let a = t.GetCustomAttributes(false).[0] :?> MyAttribute

   let e = a.Prop :?> MyEnum //Note
   Convert.ToString(e, Globalization.CultureInfo.CurrentCulture)
Run Code Online (Sandbox Code Playgroud)