2016-06-02 32 views
6

Tôi có một kiểu định nghĩa trong C# như thế này:Làm cách nào để sử dụng toán tử chuyển đổi rõ ràng quá tải?

struct F { 
    public static explicit operator F(long value) {} 
    public static explicit operator long(F value) {} 
    public static explicit operator F(double value) {} 
    public static explicit operator double(F value) {} 
    // more conversion operators 
} 

Trong F # nếu tôi muốn tạo ra nó từ lâu, cách duy nhất tôi tìm thấy là:

let l = F.op_Explicit 3L 

Tôi đã cố gắng tạo ra một inline để làm cho điều này đẹp hơn:

let inline f a = F.op_Explicit a 

Nhưng điều này không biên dịch. Tôi cũng đã thử với một ràng buộc thành viên:

let inline f (x:^a) = (F: (static member op_Explicit : ^a -> F) x) 

Và điều đó cũng không biên dịch.

Có thể xác định hàm hoặc toán tử để chọn tình trạng quá tải phải không?

Trên một mặt lưu ý, nó không làm việc độc đáo theo hướng ngược lại:

let f = someF |> int64 // calls the right conversion operator 

Trả lời

4

Nó không hợp lệ để có một hạn chế thành viên trên một loại bê tông duy nhất; Tuy nhiên, điều này có thể làm việc cho bạn:

let inline f (x:^a) : F = 
    let inline g x = ((^b or ^c):(static member op_Explicit : ^b -> ^c) x) 
    g x 

này có kiểu tổng quát hơn f : ^a -> F when (^a or F) : (static member op_Explicit : ^a -> F), mà là một loại đó là không thể tự chú thích bất kỳ giá trị với!

+0

Tuyệt vời! Chỉ lo lắng tôi có với điều này là cảnh báo: "Các ràng buộc thành viên với tên 'op_Explicit' được đưa ra bởi trạng thái đặc biệt bởi trình biên dịch F # vì một số kiểu .NET nhất định được tăng cường với thành viên này. Điều này có thể dẫn đến lỗi thời gian chạy nếu bạn cố gắng gọi ràng buộc thành viên từ mã của riêng bạn. " Tôi có thể bỏ qua nó một cách an toàn không? – Asik

+1

@Asik - Trong trường hợp này, bạn có thể bỏ qua nó. Giới hạn đó áp dụng trong một số trường hợp mà trình biên dịch hoạt động như thể có một op_Explicit mặc dù không có thực sự ở đó. Ví dụ, nếu bạn giải nén 'g' từ câu trả lời của tôi thành định nghĩa riêng của nó, gọi' (g 1: int64) 'sẽ biên dịch (vì trình biên dịch giả vờ có một chuyển đổi rõ ràng từ int thành int64), nhưng sẽ thất bại trong thời gian chạy (vì không có thành viên nào trong thực tế, việc chuyển đổi thường được xử lý bởi chính môi trường thực thi). – kvb

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