2010-04-02 63 views
6

考虑我的第一次尝试,像下面这样的简单类型在F#:如何在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") 

现在我通过C#测试此(此对象被暴露于C#项目,所以表观C#语义是期望的):

[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已正确分配,我的F#Setter正在运行,但第二个断言失败,因为基础值prop没有更改。这种情况对我来说很有意义,因为如果我从prop字段中删除mutable,则不会生成错误(并且应该是因为我试图修改该值)。我想我必须错过一个基本概念。

Test类中重新绑定/变异prop的正确方法是什么,以便我可以通过我的单元测试?

回答

8

试试这个:

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") 

你需要做结合可变的,然后改变其在二传手的价值。在你最初的代码中,你只是在你的setter中创建一个新的绑定(也叫prop),所以没有任何变化可见。

+0

谢谢,@kvb。没有什么让我觉得自己像一个简单的解决方案,在语言上像一个n00b。 :) – 2010-04-02 15:00:59

+0

@Greg - 没问题。绑定和隐藏工作的方式可能需要一些习惯,特别是因为其他语言做得如此不同。但是,一旦你的思维模式变得直白,我认为F#方法的优雅就会变得明显。 – kvb 2010-04-02 15:06:28

5

在你的模式匹配你实际上是结合了新的价值与

let prop = value 

当您绑定的同名像这样的值,它会屏蔽其他的价值,为新声明的一个范围。我相信你真正想要做的是这样的:

prop <- value 
9

作为一个侧面说明,我可能会使用if .. then代替match结构,因为它使代码更简洁(patterh匹配是特别有价值的,当你需要以再次测试多个复杂模式的值)。此外,publicmember默认访问,这样可以使代码有点更简洁:

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

我完全已经买了你的书。 :)有用的阅读,但我希望当我问这个问题时,我会保持它的方便! – 2010-04-06 13:53:49