Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The _parent and Value of the _nodes both point to the same type ( PrefixTree ), but only the _parent is marked as "AsReference".</p> <p>If you walk the serialization stack you will see that the Value of the Dictionary value is serialized independently of the _parent item and is not checked for a duplicate instance.</p> <p>As it walks the tree there is an internal serialization depth check of 25, at which it starts detecting the duplicate instances. If this value was bigger it wouldn't throw an exception, if it was smaller it would throw on a node higher up the tree.</p> <p>I also don't think this would be deserializable, and certainly if it did that the _parent field's value of each child node won't be the same instance as the _nodes container.</p> <p>You need to create you're own dictionary type ( subclass Dictionary&lt;,> or implement IDictionary&lt;,> ) so you can added the [ProtoContract] attribute and control the serialization of dictionary's items.</p> <p>ie</p> <pre><code>[ProtoContract] public class NodeItem { [ProtoMember(1)] public char Key { get; set; } [ProtoMember(2, AsReference = true)] public PrefixTree Value { get; set; } } [ProtoContract] public class Nodes : IDictionary&lt;char, PrefixTree&gt; { private readonly IDictionary&lt;char, PrefixTree&gt; inner; [ProtoMember(1)] public NodeItem[] Items { get { return this.inner.Select(item =&gt; new NodeItem() {Key = item.Key, Value = item.Value}).ToArray(); } set { foreach( NodeItem item in value) { this.inner.Add(item.Key, item.Value); } } } ... // Omitted IDictionary members for clarity </code></pre> <p>the key here is to get the AsReference metadata attached to the nodes's PrefixTree. Also note that Items is returning an Array, if you want it as a list, then you need to use set the OverwriteList attribute member. </p> <p>I also needed to remove the readonly keyword for each field in the PrefixTree type. This unit test passed for me.</p> <pre><code> [TestMethod] public void TestMethod1() { var tree = new PrefixTree(); tree.Add("racket".ToCharArray()); tree.Add("rambo".ToCharArray()); PrefixTree tree2 = null; using (var stream = new MemoryStream()) { Serializer.Serialize(stream, tree); stream.Position = 0; tree2 = Serializer.Deserialize&lt;PrefixTree&gt;(stream); } Assert.IsNotNull(tree2); Assert.AreEqual(tree._nodes.Count, tree2._nodes.Count); Assert.AreEqual(2, tree2._nodes['r']._nodes['a']._nodes.Count); // 'c' and 'm' Assert.AreEqual('c', tree2._nodes['r']._nodes['a']._nodes.Values.First().Value); Assert.AreEqual('m', tree2._nodes['r']._nodes['a']._nodes.Values.Last().Value); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload