2016-03-01 49 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