2016-03-01 14 views
9

Hãy xem đoạn mã sau đây và giả sử rằng cả hai hàm MyAttributetest không thể thay đổi.Cách bảo quản loại giá trị trong enum

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) 

Tôi mong rằng test trở B nhưng nó trả về 2. Mã IL tạo cho thấy thông tin về kiểu enum bị mất và giá trị truyền cho thuộc tính chỉ là 2.

Có cách nào (tôi đoán nó nên là một số thuộc tính) để bảo tồn loại trong giá trị thuộc tính? Whats mã tương đương thú vị hơn trong các công trình C# như mong đợi

tương đương 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

Bạn có thể chia sẻ mã C# tương đương mà bạn đã đề cập không? – MarcinJuraszek

+0

@MarcinJuraszek: chỉnh sửa – Novakov

+0

Bạn đang gọi 'GetCustomAttributes()' với 'false' trong F # và' true' trong C#; không chắc chắn những gì có, nhưng đó là một sự khác biệt ít nhất. – TeaDrivenDev

Trả lời

1

Tôi đoán và hiểu biết của tôi về bên trong của trình biên dịch thực sự yên tĩnh hạn chế nhưng tôi đoán đây là một cái gì đó để làm với loại suy luận. Có một sự tương đương giữa int < -> Enum, và tôi nghi ngờ rằng suy luận kiểu là giảm này xuống loại thấp nhất có thể, trong trường hợp này là int. Bạn có thể sửa lỗi này bằng cách thực hiện theo các cách sau

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

Vấn đề là tôi không thể thay đổi mã chịu trách nhiệm đọc thuộc tính đó - nó nằm trong thư viện khác không có kiến ​​thức về enum của tôi – Novakov

Các vấn đề liên quan