代码之家  ›  专栏  ›  技术社区  ›  Greg D

如何正确实现F#中的属性?

  •  6
  • Greg D  · 技术社区  · 16 年前

    考虑一下我的第一次尝试,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 没有改变。这对我来说是有意义的,因为如果我把 mutable 从 道具 字段,则不会生成错误(其中一个应该是因为我正在尝试对值进行变异)。我想我一定错过了一个基本概念。

    道具 在 Test 这样我就可以通过单元测试了?

    3 回复  |  直到 16 年前
        1
  •  8
  •   kvb    16 年前

    试试这个:

    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 )在你的setter里,所以没有明显的变化。

        2
  •  9
  •   Tomas Petricek    16 年前

    作为旁注,我可能会用 if .. then 而不是 match 构造,因为它使代码更加简洁(当您需要对多个复杂模式测试值时,patterh匹配尤其有价值)。也, public 是的默认访问权限 member ,这样您就可以使代码更加简洁:

    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") 
    
        3
  •  5
  •   TwentyMiles    16 年前

    在模式匹配中,实际上是将一个新值绑定到

    let prop = value
    

    当您使用相同的名称绑定这样的值时,它将在新声明的值的作用域中隐藏另一个值。我相信你真正想做的是:

    prop <- value
    
    推荐文章