如何在枚举中保留值类型

时间:2016-03-01 20:29:46

标签: 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)

我希望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)

1 个答案:

答案 0 :(得分:1)

我猜测,我对编译器内部的知识实际上是安静的,但我想这与类型推断有关。 int&lt; - &gt;之间存在等价关系。枚举,我怀疑类型推断是将其减少到可能的最低类型,在本例中为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)