Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to serialize circular referenced objects?

Better that should be text format. The best would be json, with some standart to pointers. Binary would be also good. Remember in old times, soap has standart for this. What you suggest?

like image 904
Igor Golodnitsky Avatar asked Sep 25 '11 10:09

Igor Golodnitsky


People also ask

How do you solve a circular reference in oops?

Circular reference occurs when two or more interdependent resources cause lock condition. This makes the resource unusable. To handle the problem of circular references in C#, you should use garbage collection. It detects and collects circular references.

What is a circular object reference?

A circular reference occurs when one heap variable contains a reference to a second heap variable, and the second one contains a reference back to the first. For instance, if A is an object, and somewhere in A, there is a reference to B, and within B is a reference back to A, there is a circular reference.

How do you serialize an object in .NET core?

NET objects as JSON (serialize) To write JSON to a string or to a file, call the JsonSerializer. Serialize method. The JSON output is minified (whitespace, indentation, and new-line characters are removed) by default.


1 Answers

No problem with binary whatsoever:

[Serializable]
public class CircularTest
{
    public CircularTest[] Children { get; set; }
}

class Program
{
    static void Main()
    {
        var circularTest = new CircularTest();
        circularTest.Children = new[] { circularTest };
        var formatter = new BinaryFormatter();
        using (var stream = File.Create("serialized.bin"))
        {
            formatter.Serialize(stream, circularTest);
        }

        using (var stream = File.OpenRead("serialized.bin"))
        {
            circularTest = (CircularTest)formatter.Deserialize(stream);
        }
    }
}

A DataContractSerializer can also cope with circular references, you just need to use a special constructor and indicate this and it will spit XML:

public class CircularTest
{
    public CircularTest[] Children { get; set; }
}

class Program
{
    static void Main()
    {
        var circularTest = new CircularTest();
        circularTest.Children = new[] { circularTest };
        var serializer = new DataContractSerializer(
            circularTest.GetType(), 
            null, 
            100, 
            false, 
            true, // <!-- that's the important bit and indicates circular references
            null
        );
        serializer.WriteObject(Console.OpenStandardOutput(), circularTest);
    }
}

And the latest version of Json.NET supports circular references as well with JSON:

public class CircularTest
{
    public CircularTest[] Children { get; set; }
}

class Program
{
    static void Main()
    {
        var circularTest = new CircularTest();
        circularTest.Children = new[] { circularTest };
        var settings = new JsonSerializerSettings 
        { 
            PreserveReferencesHandling = PreserveReferencesHandling.Objects 
        };
        var json = JsonConvert.SerializeObject(circularTest, Formatting.Indented, settings);
        Console.WriteLine(json);
    }
}

produces:

{
  "$id": "1",
  "Children": [
    {
      "$ref": "1"
    }
  ]
}

which I guess is what you was asking about.

like image 161
Darin Dimitrov Avatar answered Sep 22 '22 06:09

Darin Dimitrov