2016-03-01 16 views
9

让我们看看下面的一段代码,并假设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

您能分享您提到的等效C#代码吗? – MarcinJuraszek

+0

@MarcinJuraszek:编辑 – Novakov

+0

您在F#中使用'false'和C#中的'true'调用'GetCustomAttributes()';不知道这是什么,但至少有一点差异。 – TeaDrivenDev

回答

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) 
+0

问题是我无法更改负责阅读该属性的代码 - 它在另一个对我的枚举不了解的库中 – Novakov