In a farm where there is a number of cows and a number of farmers who are responsible for some of those cows, PreserveReferencesHandling reduces the size of the resulting json dramatically (45% in this case).
public class Farm
{
public List<Cow> cows;
public List<Farmer> farmers;
public List<List<Farmer>> teams;
...
}
public class Cow
{
//Some properties...
}
public class Farmer
{
public List<Cow> cows;
...
}
If PreserveReferencesHandling is turned off, this may lead to tons of cows being needlessly duplicated in the json, which, depending on whatever implementation there might be, may in fact break the program e.g. because of equality checks failing.
For example: Without PreserveReferencesHandling
// characters: 985
{
"cows": [
{"name":"SmallCow"},
{"name":"Cow"},
{"name":"BigCow"}
],
"farmers":[
{"name":"Joe", "cows":[{"name":"SmallCow"}, {"name":"Cow"}]},
{"name":"Chris", "cows":[{"name":"SmallCow"}, {"name":"BigCow"}]},
{"name":"Chris Junior", "cows":[{"name":"SmallCow"}, {"name":"BigCow"}]},
{"name":"Bob", "cows":[{"name":"SmallCow"}, {"name":"Cow"}, {"name":"BigCow"}]}
],
"teams": [
[{"name":"Joe", "cows":[{"name":"SmallCow"}, {"name":"Cow"}]}, {"name":"Chris", "cows":[{"name":"SmallCow"}, {"name":"BigCow"}]}],
[{"name":"Chris Junior", "cows":[{"name":"SmallCow"}, {"name":"BigCow"}]}, {"name":"Chris", "cows":[{"name":"SmallCow"}, {"name":"BigCow"}]}],
[{"name":"Joe", "cows":[{"name":"SmallCow"}, {"name":"Cow"}]},
{"name":"Chris", "cows":[{"name":"SmallCow"}, {"name":"BigCow"}]},
{"name":"Chris Junior", "cows":[{"name":"SmallCow"}, {"name":"BigCow"}]},
{"name":"Bob", "cows":[{"name":"SmallCow"}, {"name":"Cow"}, {"name":"BigCow"}]}]
]
}
With PreserveReferencesHandling.Objects
// characters: 547
{
"cows": [
{"$id": 0, "name":"SmallCow"},
{"$id": 1,"name":"Cow"},
{"$id": 2,"name":"BigCow"}
],
"farmers":[
{"$id": 3, "name":"Joe", "cows":[{"$ref": 0}, {"$ref": 1}]},
{"$id": 4, "name":"Chris", "cows":[{"$ref": 0}, {"$ref": 2}]},
{"$id": 5, "name":"Chris Junior", "cows":[{"$ref": 0}, {"$ref": 2}]},
{"$id": 6, "name":"Bob", "cows":[{"$ref": 0}, {"$ref": 1}, {"$ref": 2}]}
],
"teams": [
[{"$ref" : 3}, {"$ref" : 4}],
[{"$ref" : 5}, {"$ref" : 4}],
[{"$ref" : 3}, {"$ref" : 4}, {"$ref" : 5}, {"$ref" : 6}]
]
}
This example is somewhat engineered to show the difference, but I would assume this memory saving would only get more pronounced the more complex and interconnected a data system becomes.
What are the pros and cons of PreserveReferenceHandling? Which setting is most useful, PreserveReferenceHandling.Objects, PreserveReferenceHandling.Arrays or PreserveReferenceHandling.All?