2010-04-02 32 views
6

xem xét nỗ lực đầu tiên của tôi, một kiểu đơn giản trong F # như sau:Làm cách nào để triển khai đúng thuộc tính trong F #?

type Test() = 
    inherit BaseImplementingNotifyPropertyChangedViaOnPropertyChanged() 
    let mutable prop: string = null 
    member this.Prop 
     with public get() = prop 
     and public set value = 
      match value with 
       | _ when value = prop ->() 
       | _ -> 
        let prop = value 
        this.OnPropertyChanged("Prop") 

Bây giờ tôi thử nghiệm này qua C# (đối tượng này đã được tiếp xúc với một dự án C#, vì vậy rõ ràng C# ngữ nghĩa là mong muốn):

[TestMethod] 
public void TaskMaster_Test() 
{ 
    var target = new FTest(); 
    string propName = null; 
    target.PropertyChanged += (s, a) => propName = a.PropertyName; 
    target.Prop = "newString"; 

    Assert.AreEqual("Prop", propName); 
    Assert.AreEqual("newString", target.Prop); 

    return; 
} 

propName được chỉ định đúng, F # Setter của tôi đang chạy, nhưng khẳng định thứ hai không thành công vì giá trị cơ bản của prop không thay đổi. Điều này có ý nghĩa với tôi, bởi vì nếu tôi loại bỏ mutable từ trường prop, không có lỗi nào được tạo ra (và một là vì tôi đang cố gắng làm biến đổi giá trị). Tôi nghĩ tôi phải thiếu một khái niệm cơ bản.

Cách chính xác để rebind/mutate prop trong lớp học Test để tôi có thể vượt qua bài kiểm tra đơn vị của mình là gì?

Trả lời

8

Hãy thử điều này:

type Test() = 
    inherit BaseImplementingNotifyPropertyChangedViaOnPropertyChanged() 
    let mutable prop: string = null 
    member this.Prop 
     with public get() = prop 
     and public set value = 
      match value with 
       | _ when value = prop ->() 
       | _ -> 
        prop <- value 
        this.OnPropertyChanged("Prop") 

Bạn cần phải thực hiện có thể thay đổi ràng buộc và sau đó thay đổi giá trị của nó trong setter của bạn. Trong mã ban đầu của bạn, bạn chỉ cần tạo một ràng buộc mới (cũng được gọi là prop) trong trình thiết lập của bạn, vì vậy không có thay đổi nào được hiển thị.

+0

Cảm ơn, @kvb. Không có gì làm cho tôi cảm thấy như một n00b ở ngôn ngữ hơn là một sửa chữa đơn giản như vậy. :) –

+0

@Greg - không sao cả. Cách mà các ràng buộc và việc làm bóng có thể mất một chút để làm quen, đặc biệt là vì các ngôn ngữ khác làm việc khác nhau. Tuy nhiên, một khi bạn nhận được mô hình tinh thần của bạn thẳng, tôi nghĩ rằng sự sang trọng của cách tiếp cận F # trở nên rõ ràng. – kvb

5

Trong mô hình phù hợp của bạn, bạn đang thực sự ràng buộc một giá trị mới với

let prop = value 

Khi bạn liên kết một giá trị như thế này có cùng tên, nó sẽ bóng giá trị khác cho phạm vi mới được tuyên bố một. Tôi tin vào những gì bạn thực sự muốn làm là thế này:

prop <- value 
9

Là một phụ lưu ý, tôi có lẽ sẽ sử dụng if .. then thay vì match xây dựng vì nó làm cho mã gọn gàng hơn (phù hợp patterh đặc biệt có giá trị khi bạn cần để kiểm tra giá trị lặp lại nhiều mẫu phức tạp). Ngoài ra, public là truy cập mặc định cho member, vì vậy bạn có thể làm cho đoạn code một chút gọn gàng hơn:

type Test() = 
    inherit BaseImplementingNotifyPropertyChangedViaOnPropertyChanged() 
    let mutable prop : string = null 
    member this.Prop 
     with get() = prop 
     and set(value) = 
      if value <> prop then 
       prop <- value 
       this.OnPropertyChanged("Prop") 
+1

Tôi hoàn toàn đã mua sách của bạn. :) Đọc hữu ích, mặc dù tôi muốn tôi giữ nó tiện dụng khi tôi hỏi câu hỏi này! –

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