How to properly implement a property in F #?

Consider my first attempt, a simple type in F #, for example:

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

Now I am testing this through C # (this object undergoes a C # project, so C # semantics are obvious):

 [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 correctly assigned, my F # setter is running, but the second statement does not work, because the base value of prop does not change. This makes sense to me because if I remove the mutable from the prop field, the error will not be generated (and this should be because I'm trying to change the value). I think that I am missing a fundamental concept.

What is the correct way to recompute / mutate prop in the Test class so that I can pass my unit test?

+6
mutable f #
source share
3 answers

Try the following:

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

You need to make the binding mutable, and then change its value in the customizer. In your source code, you just created a new binding (also called prop ) inside your setter, so no changes were visible.

+8
source share

As a side note, I would probably use if .. then instead of the match construct, as it makes the code shorter (patterh matching is especially valuable when you need to check the value again for a few complex patterns). In addition, public is the default access for member , so you can make the code a bit more concise:

 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") 
+9
source share

In your pattern match, you actually bind the new value with

 let prop = value 

When you bind a value like this with the same name, it obscures the other value for the area just declared. I believe you really want to do this:

 prop <- value 
+5
source share

All Articles