How can I configure NewtonSoft to set a property via the property setter? - f#

When I deserialize some JSON into this F# class, the property setter for the CountResults property is not working as expected.
I have this class:
type CounterResponse () =
let mutable countsList:List<CountResult> = List<CountResult>()
let mutable countResultsLookup:IReadOnlyDictionary<string,int> = readOnlyDict [("", 0)]
member this.CountResults
with get() = countsList
and set(value:List<CountResult>) =
countResultsLookup <- value |> Seq.map(fun c -> c.Name, c.Count) |> readOnlyDict
countsList <- value
...
If I create an instance of this class with F# using:
let countResults = seq {
{Name = "Count01"; Count = count}
{Name = "Count02"; Count = count}
{Name = "Count03"; Count = count}
}
let response = CountersResponse(CountResults = List<CountResult>(countResults))
Then the CountResults property setter runs and sets the values of the private backing fields countsList and countResultsLookup.
However, when I create an instance of this class with NewtonSoft.Json only the countsList backing field is set and I can't get the breakpoint in the setter code to stop. It appears that NewtonSoft is bypassing my property setter code, finding the countsList backing field, and setting it directly.
let response = JsonConvert.DeserializeObject<CounterResponse>(
"""
{
"countResults": [
{ "name": "Count01","count": 4 },
{ "name": "Count02", "count": 2 },
{ "name": "Count3", "count": 1 },
],
"version": "6.0.0.0",
"errorSection": {
"validationErrors": [],
"code": "200",
"message": "Success"
}
}
"""
)
In the above example the backing field countResultsLookup is set to the default value readOnlyDict [("", 0)] and countList contains the 3 counts in the JSON.
Is there an option to tell NewtonSoft to use the property setter so that I can get the expected results in both cases?

Your problem here is the same as the problem from Why are all the collections in my POCO are null when deserializing some valid json with the .NET Newtonsoft.Json component. When Json.NET deserializes a member whose value is a mutable list, it calls the getter to see if the list has already been constructed. If so, it populates the returned list as-is, and never sets it back. Thus, since your CountResults property is in fact pre-allocated, the logic to build the countResultsLookup dictionary is never invoked.
To work around the problem, you could adopt one of the solutions from that question such as marking the CountResults property with [<JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)>]:
[<JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)>]
member this.CountResults
with get() = countsList
and set(value:List<CountResult>) =
countResultsLookup <- value |> Seq.map(fun c -> c.Name, c.Count) |> readOnlyDict
countsList <- value
This requires Json.NET to construct a fresh list and set it back after it is fully deserialized.
Demo fiddle #1 here.
That being said, I can't really recommend this design. Your type CounterResponse contains a mutable list property and a read-only dictionary that provides lookups into the list -- but makes no effort to keep these two collections synchronized. If you need mutability for your CountResults, consider creating a custom collection that inherits from KeyedCollection<TKey,TItem> and provides the necessary lookup facility.
Assuming that CountResult looks like this:
type CountResult = { Name : string; Count : int }
You can define CounterResponse as follows:
type CountResultCollection() =
inherit System.Collections.ObjectModel.KeyedCollection<string,CountResult>()
override this.GetKeyForItem i = i.Name
type CounterResponse (l : CountResult seq) =
let countList = CountResultCollection()
do
for c in l do countList.Add(c)
new() = CounterResponse(Seq.empty)
member this.CountResults = countList
And now the methods CountResults.Item(s : string) and CountResults.TryGetValue() will be usable to locate count results by name.
Demo fiddle #2 here.

Related

When to use F#'s typedefof<'T> vs. typeof<'T>?

Can someone clarify when to use typedefof<'T> vs. typeof<'T>?
Both typedefof<System.String> and typeof<System.String> return the same Type instance.
However, they return different instances and different information for System.Collections.Generic.List<_>.
Can I think of typedefof as a new and improved typeof? Should I just switch to always using typedefof? Or is it more subtle than that?
This ought to illustrate the difference. When you use typeof, the compiler infers type arguments and constructs a concrete type. In this case, the inferred type argument is System.Object:
let t1 = typeof<System.Collections.Generic.List<_>>
let t2 = typedefof<System.Collections.Generic.List<_>>
printfn "t1 is %s" t1.FullName
printfn "t2 is %s" t2.FullName
Output:
t1 is System.Collections.Generic.List`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
t2 is System.Collections.Generic.List`1
Because typeof can only return a constructed type, typedefof is necessary if you need a type object representing a generic type definition.
typeof is used when you want to get the System.Type object for a given type. typedefof is used when you want to get the System.Type that represents the type definition for a generic type. As an example that uses both, suppose you had a type called Generic<'a>, and you wanted to create a function that returned the System.Type object for the Generic of any given type.
type Generic<'a> = Value of 'a
let makeGenericOf<'a> () =
typedefof<Generic<_>>.MakeGenericType(typeof<'a>)
Here, you would use the typedefof function to get the type defintion, and typeof to get the type of 'a for constructing the generic Generic<'a> Type.
I really appreciate the answers from phoog, Aaron, and JLRishe. Here is what I have learned, based on their answers and my own experimentation.
There are two Type instances associated with generics.
There is a Type associated with a generic that has specific type parameters. For example, there is a Type associated with List<int> and a different Type associated with List<string>. This is what you get when you use typeof<>.
> typeof<List<string>>.ToString();;
val it : string = "Microsoft.FSharp.Collections.FSharpList`1[System.String]"
> typeof<List<int>>.ToString();;
val it : string = "Microsoft.FSharp.Collections.FSharpList`1[System.Int32]"
There is a Type associated with the generic type definition itself. For example, there is a single Type associated with List<'T>, which is the same for List<int>, List<string>, and List<_>. This is what you get when you use typedefof<>.
> typedefof<List<string>>.ToString();;
val it : string = "Microsoft.FSharp.Collections.FSharpList`1[T]"
> typedefof<List<int>>.ToString();;
val it : string = "Microsoft.FSharp.Collections.FSharpList`1[T]"
> typedefof<List<_>>.ToString();;
val it : string = "Microsoft.FSharp.Collections.FSharpList`1[T]"
By the way, the Type class has an instance method to GetGenericTypeDefinition(). That means, the following two return the same instance:
> Object.ReferenceEquals(typeof<List<int>>.GetGenericTypeDefinition(), typedefof<List<int>>);;
val it : bool = true
What happens if you call typeof<List<_>>? You get back the Type definition for List<Object>, as phoog mentioned.
> typeof<List<_>>.ToString();;
val it : string = "Microsoft.FSharp.Collections.FSharpList`1[System.Object]"
This is all helpful to understand. For example, suppose I need to know if an object is a generic list (of any type).
// does not give me the answer I naively expected
> o.GetType() = typeof<List<_>>;;
val it : bool = false
// does this reference point to a List<'T>?
> o.GetType().IsGenericType && o.GetType().GetGenericTypeDefinition() = typedefof<List<_>>;;
val it : bool = true
Additionally, if you want to late-bound instantiate a generic type, you can use the MakeGenericType(...) method which Aaron mentioned.
> let myList = typedefof<List<_>>.MakeGenericType(typeof<int>);;
val myList : Type = Microsoft.FSharp.Collections.FSharpList`1[System.Int32]

Does record type with key exist in F#

In OPL (Optimization Programming Language), we have a data structure name tuple. OPL tuple correspond to Record in F#. Here is how it is defined:
tuple Point {
int x;
int y;
};
Like in F#, we can access field by using dot notation
int x = p.x;
We can group tuples in a Set:
{Point} points = {<1,2>, <2,3>};
A difference is that like in database systems, tuple structures can be associated with keys. Tuple keys enable to access data organized in tuples using a set of unique identifiers. In the following example, the nurse tuple is declared with the key name of type string.
tuple nurse {
key string name;
int seniority;
int qualification;
int payRate;
}
{ nurse } nurses = …;
The nice thing about key, is that we can initialize an array this way
int NumberOfChild [n in nurses] = 0;
and accessing a value by using only the key:
NumberOfChild[<"Isabelle">]=20;
leaving out the fields with no keys. This is equivalent to:
NumberOfChild[<"Isabelle",3,1,16>]=20;
Also, using key means that there will be no two tuples with the same key. Like primary key in database.
Question is: Does some type like this exist in F#? Record with key?
My goal: I would like to define a node structure with many attribute. And load a graph structure by only giving the key of the node and not the entire Record since I would load the graph from a database.
type Node = {
nodeKey : int;
nodeName : string;
nodeAttribute1 : string;
nodeAttribute2 : string }
let Graph = [
(1, 2);
(1, 3);
(2, 4);
(3, 4) ]
Where the int in the graph tuple represent nodeKey.
I would like to do operation using the graph but accessing the node information using the key only.
OPL Grammar
No, there's no such language-level concept. All record fields are created equal, so to speak.
That doesn't preclude you from:
synthesizing a key for a record based on one or more field values,
using such a key as a key in a Map that would hold your records or any additional values.
So you can have something like this:
type Nurse = { name: string; seniority: int; qualification: int; payRate: int }
let nurses = [ { name = "Isabelle"; seniority = 3; qualification = 1; payRate = 16 } ]
let numberOfChildren =
[ "Isabelle", 20 ]
|> Map.ofSeq
let nursesWithNumberOfChildren =
[ for nurse in nurses do
match numberOfChildren |> Map.tryFind nurse.name with
| Some children -> yield nurse, children
| None -> yield nurse, 0 ]
Using similar approach you can separate your graph and node data - store only keys in the graph and maintain a mapping that goes from keys to full node records.
//If I read data from a database, I would receive the data in the following form:
type XYZ = {X:int;
Y:string;
Z:float}
let recordsXYZ = [{X=1;Y="A";Z=1.0};{X=2;Y="b";Z=1.0};{X=3;Y="A";Z=1.0}]
//I can create a map this way
let mapXYZ1=recordsXYZ|>Seq.groupBy (fun a ->a.X)|>Map.ofSeq
//But I don't want a Map<int,seq<XYZ>>
//This is what I want
let mapXYZ2=recordsXYZ|>Seq.map (fun a -> (a.X,{X=a.X;Y=a.Y;Z=a.Z}))|>Map.ofSeq
//Or maybe this is cleaner but this need to define another type
type YZ = {Y:string;
Z:float}
let mapXYZ3=recordsXYZ|>Seq.map (fun a -> (a.X,{Y=a.Y;Z=a.Z}))|>Map.ofSeq
If I understand correctly, your best bet is simply a cleaner alternative to Seq.groupBy for your purposes. Here is the core of it, in one line:
let inline project projection value = projection value, value
Given a simple helper function, not specific to XYZ
let projectToMap projection values = values |> Seq.map (project projection) |> Map.ofSeq
it becomes trivial to cleanly create maps of XYZ from any "key":
let mappedByX = xyzs |> projectToMap (fun { X=x } -> x) // Map<int, XYZ>
let mappedByY = xyzs |> projectToMap (fun { Y=y } -> y) // Map<string, XYZ>
let mappedByZY = xyzs |> projectToMap (fun { Y=y; Z=z } -> z, y) // Map<float*string, XYZ>
Online Demo

Why does dict allow duplicate inserts?

why in the world does the constructor for a dictionary in F# allow duplicate keys and just overwrites silently?
let ``you just got dict`` = dict [ "hello","goodbye";"hello","world"]
This is very counter-intuitive behavior.
You could shadow the built-in dict function with a version that behaves as you want. You could return the more fitting IReadOnlyDictionary interface while you're at it.
let dict source =
let d = Dictionary<'K, 'V>(HashIdentity.Structural)
source |> Seq.iter d.Add
{
new IReadOnlyDictionary<'K, 'V> with
member x.ContainsKey(key) = d.ContainsKey(key)
member x.TryGetValue(key, value) = d.TryGetValue(key, &value)
member x.Item with get key = d.[key]
member x.Keys = d.Keys :> _
member x.Values = d.Values :> _
interface IReadOnlyCollection<KeyValuePair<'K, 'V>> with
member x.Count = d.Count
interface IEnumerable<KeyValuePair<'K, 'V>> with
member x.GetEnumerator() = d.GetEnumerator() :> _
interface System.Collections.IEnumerable with
member x.GetEnumerator() = d.GetEnumerator() :> _
}
I can't explain the reason for this design - just as I can't explain why Dictionary<TKey, TValue> doesn't take a sequence of KeyValuePairs as input.
However, if you look at the implementation of dict, you'll see that it internally adds each element using the indexer, like this:
foreach (Tuple<TKey, TValue> tuple in keyValuePairs)
{
TValue local = tuple.Item2;
TKey local2 = tuple.Item1;
d[new RuntimeHelpers.StructBox<TKey>(local2)] = local;
}
where d is the Dictionary being created. The indexer silently updates the dictionary entry, so this explains the mechanics of it.
Not an entire answer, I admit, but perhaps a piece of the puzzle.
You aren't going to get a why unless some Microsoft engineer explains it to you why they chose to do it that way. Regardless, it is what it is and works just as the documentation says it should:
https://msdn.microsoft.com/en-us/library/k7z0zy8k(v=vs.110).aspx
Remarks
You can also use the Item property to add new elements by setting the value
of a key that does not exist in the Dictionary<TKey, TValue>; for example,
myCollection[myKey] = myValue (in Visual Basic, myCollection(myKey) =
myValue). However, if the specified key already exists in the
Dictionary<TKey, TValue>, setting the Item property overwrites the old
value. In contrast, the Add method throws an exception if a value with the
specified key already exists.

Critique of immutable classes with circular references design, and better options

I have a factory class that creates objects with circular references. I'd like them to be immutable (in some sense of the word) too. So I use the following technique, using a closure of sorts:
[<AbstractClass>]
type Parent() =
abstract Children : seq<Child>
and Child(parent) =
member __.Parent = parent
module Factory =
let makeParent() =
let children = ResizeArray()
let parent =
{ new Parent() with
member __.Children = Seq.readonly children }
[Child(parent); Child(parent); Child(parent)] |> children.AddRange
parent
I like this better than an internal AddChild method because there's a stronger guarantee of immutability. Perhaps it's neurotic, but I prefer closures for access control.
Are there any pitfalls to this design? Are there better, perhaps less cumbersome, ways to do this?
You can use F#'s support for recursive initialization even when creating an instance of abstract class:
let makeParent() =
let rec children = seq [ Child(parent); Child(parent); Child(parent) ]
and parent =
{ new Parent() with
member __.Children = children }
parent
When compiling the code, F# uses lazy values, so the value children becomes a lazy value and the property Children accesses the value of this lazy computation. This is fine, because it can first create instance of Parent (referencing the lazy value) and then actually construct the sequence.
Doing the same thing with records wouldn't work as nicely, because none of the computations would be delayed, but it works quite nicely here, because the sequence is not actually accessed when creating the Parent (if it was a record, this would be a field that would have to be evaluated).
The F# compiler cannot tell (in general) whether this is correct, so it emits a warning that can be disabled using #nowarn "40".
In general, I think that using let rec .. and .. to initialize recursive values is a good thing - it is a bit limited (one of the references must be delayed), but it forces you to keep the recursive references isolated and, I think, it keeps your code simpler.
EDIT To add an example when this may go wrong - if the constructor of Child tries to access the Children collection of its parent, then it forces evaluation of the lazy value before it can be created and you get a runtime error (which is what the warning says). Try adding this to the constructor of Child:
do printfn "%d" (Seq.length parent.Children)
I think that Tomas's answer is the way to go. However, for completeness I'll show how you could use recursive records to create cyclic immutable objects. This can potentially get quite ugly, so I've hidden the immutable record implementation behind some nicer properties:
type Parent = internal { children : Children option }
and internal Children = { first : Child; rest : Children option }
and Child = internal { parent : Parent }
let rec internal listToChildren = function
| [] -> None
| c::cs -> Some { first = c; rest = listToChildren cs }
let rec internal childrenToList = function
| None -> []
| Some { first = c; rest = cs } -> c::(childrenToList cs)
module Factory =
let makeParent() =
let rec parent = { children = children }
and child1 = { parent = parent }
and child2 = { parent = parent }
and child3 = { parent = parent }
and children = [child1; child2; child3] |> listToChildren
parent
type Parent with
member p.Children = childrenToList p.children
type Child with
member c.Parent = c.parent
I guess something like this can also be done:
type ParentFactory private (n) as X =
inherit Parent()
let childs = [for i=1 to n do yield Child(X :> Parent)]
override X.Children = childs |> List.toSeq;
static member Create n = (new ParentFactory(n)) :> Parent

How do I properly implement a property in F#?

Consider my first attempt, a simple type in F# like 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 -> ()
| _ ->
let prop = value
this.OnPropertyChanged("Prop")
Now I test this via C# (this object is being exposed to a C# project, so apparent C# semantics are desirable):
[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 is properly assigned, my F# Setter is running, but the second assert is failing because the underlying value of prop isn't changed. This sort of makes sense to me, because if I remove mutable from the prop field, no error is generated (and one should be because I'm trying to mutate the value). I think I must be missing a fundamental concept.
What's the correct way to rebind/mutate prop in the Test class so that I can pass my unit test?
As a side-note, I would probably use if .. then instead of the match construct as it makes the code more succinct (patterh matching is especially valuable when you need to test the value agains multiple complex patterns). Also, public is the default access for member, so you can make the code a bit more succinct:
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")
Try this:
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 alter its value in your setter. In your initial code, you were just creating a new binding (also called prop) within your setter, so no change was visible.
In your pattern match you are actually binding a new value with
let prop = value
When you bind a value like this with the same name, it will shadow the other value for the scope of the newly declared one. I believe what you actually want to do is this:
prop <- value

Resources