2011-09-07 31 views
6

Tôi có đoạn mã sau:F # phân biệt đối xử đoàn so với C# lớp phân cấp

public abstract class A ... 
public class B : A ... 
public class C : A ... 

void my_fct(A x) { 
    if (x is B) { block_1 } 
    else if (x is C) { block_2 } 
    else { block_3 } 
} 

và tôi tự hỏi nếu nó là một bản dịch tốt từ F #

type a = B | C 
let my_fct x = 
    match x with 
    | B -> (block_1) 
    | C -> (block_2) 
    | _ -> (block_3) 

??

+0

Tôi đoán là không sao. Ngoại trừ việc bạn đang bỏ lỡ; sau block_1, block_2 và block_3 –

+2

Xin lỗi vì sự thiếu hiểu biết của tôi, nhưng có vẻ như 'block_3' không bao giờ được thực hiện trong đoạn mã F # (các kiểu dữ liệu đại số được "đóng" theo như tôi biết), vậy tại sao lại có? Ngoài ra, tôi là người duy nhất nghĩ rằng bản dịch nên sử dụng đa hình? – delnan

+0

Bạn hoàn toàn đúng về block_3. – Hugo

Trả lời

11

F # phân biệt đối xử tương ứng với phân cấp lớp OO khá chặt chẽ, vì vậy đây có lẽ là lựa chọn tốt nhất. Sự khác biệt đáng chú ý nhất là bạn không thể thêm các trường hợp mới vào một công đoàn bị phân biệt đối xử mà không sửa đổi khai báo kiểu. Mặt khác, bạn có thể dễ dàng thêm các hàm mới hoạt động với kiểu (tương đương với việc thêm các phương thức ảo mới trong C#).

Vì vậy, nếu bạn không muốn thêm các lớp mới được thừa hưởng (trường hợp), thì đây là tùy chọn tốt nhất. Nếu không, bạn có thể sử dụng các loại đối tượng F # (hoặc các tùy chọn khác, tùy thuộc vào kịch bản).

Một điểm nữa về mã của bạn - vì bạn không thể thêm trường hợp mới, trình biên dịch F # biết rằng các trường hợp duy nhất bạn cần là dành cho BC. Kết quả là, block_3 không bao giờ có thể được thực thi, có nghĩa là bạn có thể viết chỉ:

let my_fct x = 
    match x with 
    | B -> (block_1) 
    | C -> (block_2) 
7

có điều này ít nhiều giống với F #. Trong trường hợp này (không có giá trị được thêm) - F # dường như dịch thành một lớp cho "a" và một số Thẻ (liệt kê). Lớp cho "a" chỉ có một số đặc tính tĩnh cho B và C, và một số phương pháp để kiểm tra xem một đối tượng kiểu "a" là "B" hoặc "C" (xem dưới đây)

Object-Browser of the types

Nhưng bạn không cần "_ -> (block_3)" trường hợp, bởi vì điều này không bao giờ có thể được xuất hiện (F # biết tất cả các trường hợp có thể và sẽ cảnh báo bạn).

Tôi nghĩ sẽ tốt hơn nếu bạn ném ngoại lệ trong C# cho trường hợp "khác" này.

+0

tôi đoán Tomas sẽ đẹp hơn;) – Carsten

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