2010-03-05 28 views

Trả lời

33

Trình sửa đổi protected có thể khá rắc rối trong F #, vì bạn thường cần gọi các thành viên từ biểu thức lambda. Tuy nhiên, khi bạn làm điều đó, bạn không còn truy cập phương thức từ bên trong lớp nữa. Điều này cũng gây nhầm lẫn khi sử dụng các thành viên được bảo vệ được khai báo trong C# (xem ví dụ this SO question). Nếu bạn có thể khai báo một thành viên protected, đoạn code sau có thể là đáng ngạc nhiên:

type Base() = 
    protected member x.Test(a) = a > 10 

type Inherited() = 
    inherit Base() 
    member x.Filter(list) = 
    list |> List.filter (fun a -> x.Test(a)) 

Mã này sẽ không làm việc, bởi vì bạn đang gọi điện thoại Test từ một hàm lambda (mà là một đối tượng khác với trường hợp hiện tại của Test), vì vậy mã sẽ không hoạt động. Tôi nghĩ rằng đây là lý do chính để không hỗ trợ sửa đổi protected trong F #.

Trong F #, bạn thường sử dụng thừa kế thực hiện (có nghĩa là kế thừa từ một lớp cơ sở) ít thường xuyên hơn trong C#, vì vậy bạn không nên cần protected như thường lệ. Thay vào đó, nó thường được ưu tiên sử dụng các giao diện (trong mã F # hướng đối tượng) và các hàm bậc cao hơn (trong mã chức năng). Tuy nhiên, rất khó để nói làm thế nào để tránh sự cần thiết cho protected nói chung (khác hơn là tránh việc thừa kế thực hiện). Bạn có một số ví dụ cụ thể thúc đẩy câu hỏi của bạn?

+26

Điều này đúng, nhưng đó là một hiện vật thực hiện của trình biên dịch. Không có lý do cơ bản nào mà ngôn ngữ .NET giống như F # không thể tạo ra một lớp lồng nhau để đóng gói và có ngữ nghĩa dự định. – kvb

+0

Giải thích tốt. Thật dễ dàng để quên đi các đối tượng mà trình biên dịch F # tạo ra để hỗ trợ lambdas và các cấu trúc chức năng khác. Tôi đang viết một ORM sẽ được sử dụng thường xuyên từ C#. Nó sử dụng một cái gì đó của một mô hình nhà cung cấp. Có một lớp Repository trừu tượng, có thể được mở rộng bởi SqlRepository, OracleRepository, vv Tôi muốn một phương thức được bảo vệ tải thông tin lược đồ cho một bảng. Bất kỳ ý tưởng của một cách tốt hơn để làm điều này? – Daniel

+0

@kvb - Tôi cũng nghĩ như vậy. Có cách nào trình biên dịch có thể kiểm tra xem một thành viên được bảo vệ có đang được truy cập từ một lambda trong một lớp dẫn xuất không? – Daniel

7

Để xem liệu F # có cho phép tạo mô hình dữ liệu tốt hơn hay không, các tệp chữ ký cho phép các quyết định tầm nhìn rõ ràng hơn internal thực hiện trong C#, thường rất đẹp. Xem nhận xét của Brian here để được giải thích thêm một chút. Tuy nhiên, điều này độc lập với sự hỗ trợ (hoặc thiếu) cho protected.

+0

liên kết dường như đã chết – Maslow

+0

@Maslow - Cảm ơn bạn đã chỉ ra điều này; Tôi đã cập nhật liên kết đến những gì tôi nghĩ là một tấm gương của bài đăng gốc. – kvb

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