title: Proto-Buf.Net and serialization
body: <p>I've a problem with serializing an object using protobuf.net. I've used it on other classes and it works very well, but using this it doesn't.</p>
  
  <p>Could you help me saying why. Thanks.</p>
  
  <p>I want to use protobuf because BinaryFormatter is very slow in serializing/deserializing.</p>
  
  <p>This is the class:</p>
  
  <pre><code>using System.Collections.Generic;
  using System;
  using ProtoBuf;
  using System.Xml.Serialization;
  using System.Runtime.Serialization;
  
  namespace RadixTree
  {
  [Serializable, DataContract, ProtoContract]
  public class Node&lt;T&gt;
  {
      private readonly List&lt;Node&lt;T&gt;&gt; children = new List&lt;Node&lt;T&gt;&gt;();
      private readonly string key;
      private T value;
      public Node(string key, T value)
      {
          this.key = key;
          this.value = value;
      }
      private Node()
      {
      }
      protected bool HasChildren
      {
          get { return children.Count &gt; 0; }
      }
      public void Insert(string key, T value)
      {
          var potentialChild = new Node&lt;T&gt;(key, value);
          Add(potentialChild);
      }
      private bool Add(Node&lt;T&gt; theNewChild)
      {
          if (Contains(theNewChild))
              throw new DuplicateKeyException(string.Format("Duplicate key: '{0}'", theNewChild.key));
  
          if (!IsParentOf(theNewChild))
              return false;
  
          bool childrenObligedRequest = RequestChildrenToOwn(theNewChild);
          if (childrenObligedRequest) return true;
  
          AcceptAsOwnChild(theNewChild);
          return true;
      }
      private bool RequestChildrenToOwn(Node&lt;T&gt; newChild)
      {
          return
              children.Exists(
                  existingChild =&gt;
                  existingChild.MergeIfSameAs(newChild) || existingChild.Add(newChild) ||
                  ForkANewChildAndAddChildren(existingChild, newChild));
      }
      private bool MergeIfSameAs(Node&lt;T&gt; potentialChild)
      {
          if (!IsTheSameAs(potentialChild) || IsNotUnrealNode())
              return false;
  
          value = potentialChild.value;
          return true;
      }
      private bool IsNotUnrealNode()
      {
          return !IsUnrealNode();
      }
      private void Disown(Node&lt;T&gt; existingChild)
      {
          children.Remove(existingChild);
      }
      private Node&lt;T&gt; AcceptAsOwnChild(Node&lt;T&gt; child)
      {
          if (NotItself(child)) children.Add(child);
          return this;
      }
      private bool NotItself(Node&lt;T&gt; child)
      {
          return !Equals(child);
      }
      private bool ForkANewChildAndAddChildren(Node&lt;T&gt; existingChild, Node&lt;T&gt; newChild)
      {
          if (existingChild.IsNotMySibling(newChild))
              return false;
  
          var surrogateParent = MakeASurrogateParent(existingChild, newChild);
          if (surrogateParent.IsTheSameAs(this))
              return false;
  
          SwapChildren(existingChild, newChild, surrogateParent);
          return true;
      }
      private bool IsNotMySibling(Node&lt;T&gt; newChild)
      {
          return !IsMySibling(newChild);
      }
      private void SwapChildren(Node&lt;T&gt; existingChild, Node&lt;T&gt; newChild, Node&lt;T&gt; surrogateParent)
      {
          surrogateParent.AcceptAsOwnChild(existingChild)
              .AcceptAsOwnChild(newChild);
  
          AcceptAsOwnChild(surrogateParent);
          Disown(existingChild);
      }
      private Node&lt;T&gt; MakeASurrogateParent(Node&lt;T&gt; existingChild, Node&lt;T&gt; newChild)
      {
          string keyForNewParent = existingChild.CommonBeginningInKeys(newChild);
          keyForNewParent = keyForNewParent.Trim();
          var surrogateParent = new Node&lt;T&gt;(keyForNewParent, default(T));
  
          return surrogateParent.IsTheSameAs(newChild) ? newChild : surrogateParent;
      }
      private bool IsTheSameAs(Node&lt;T&gt; parent)
      {
          return Equals(parent);
      }
      private bool IsMySibling(Node&lt;T&gt; potentialSibling)
      {
          return CommonBeginningInKeys(potentialSibling).Length &gt; 0;
      }
      private string CommonBeginningInKeys(Node&lt;T&gt; potentialSibling)
      {
          return key.CommonBeginningWith(potentialSibling.key);
      }
      internal virtual bool IsParentOf(Node&lt;T&gt; potentialChild)
      {
          return potentialChild.key.StartsWith(key);
      }
      public bool Delete(string key)
      {
          Node&lt;T&gt; nodeToBeDeleted = children.Find(child =&gt; child.Find(key) != null);
          if (nodeToBeDeleted == null) return false;
  
          if (nodeToBeDeleted.HasChildren)
          {
              nodeToBeDeleted.MarkAsUnreal();
              return true;
          }
  
          children.Remove(nodeToBeDeleted);
          return true;
      }
      private void MarkAsUnreal()
      {
          value = default(T);
      }
      public T Find(string key)
      {
          var childBeingSearchedFor = new Node&lt;T&gt;(key, default(T));
          return Find(childBeingSearchedFor);
      }
      private T Find(Node&lt;T&gt; childBeingSearchedFor)
      {
          if (Equals(childBeingSearchedFor)) return value;
          T node = default(T);
          children.Find(child =&gt;
                            {
                                node = child.Find(childBeingSearchedFor);
                                return node != null;
                            });
          if (node == null) return default(T);
          return node;
      }
      public bool Contains(string key)
      {
          return Contains(new Node&lt;T&gt;(key, default(T)));
      }
      private bool Contains(Node&lt;T&gt; child)
      {
          if (Equals(child) &amp;&amp; IsUnrealNode()) return false;
  
          if (Equals(child)) return true;
  
          return children.Exists(node =&gt; node.Contains(child));
      }
      private bool IsUnrealNode()
      {
          return value == null;
      }
      public List&lt;T&gt; Search(string keyPrefix)
      {
          var nodeBeingSearchedFor = new Node&lt;T&gt;(keyPrefix, default(T));
          return Search(nodeBeingSearchedFor);
      }
      private List&lt;T&gt; Search(Node&lt;T&gt; nodeBeingSearchedFor)
      {
          if (IsTheSameAs(nodeBeingSearchedFor))
              return MeAndMyDescendants();
  
          return SearchInMyChildren(nodeBeingSearchedFor);
      }
      private List&lt;T&gt; SearchInMyChildren(Node&lt;T&gt; nodeBeingSearchedFor)
      {
          List&lt;T&gt; searchResults = null;
  
          children.Exists(existingChild =&gt; (searchResults = existingChild.SearchUpAndDown(nodeBeingSearchedFor)).Count &gt; 0);
  
          return searchResults;
      }
      private List&lt;T&gt; SearchUpAndDown(Node&lt;T&gt; node)
      {
          if (node.IsParentOf(this))
              return MeAndMyDescendants();
  
          return IsParentOf(node) ? Search(node) : new List&lt;T&gt;();
  
      }
      private List&lt;T&gt; MeAndMyDescendants()
      {
          var meAndMyDescendants = new List&lt;T&gt;();
          if (!IsUnrealNode())
              meAndMyDescendants.Add(value);
  
          children.ForEach(child =&gt; meAndMyDescendants.AddRange(child.MeAndMyDescendants()));
          return meAndMyDescendants;
      }
      public long Size()
      {
          const long size = 0;
          return Size(size);
      }
      private long Size(long size)
      {
          if (!IsUnrealNode())
              size++;
  
          children.ForEach(node =&gt; size += node.Size());
          return size;
      }
      public override string ToString()
      {
          return key;
      }
      public bool Equals(Node&lt;T&gt; other)
      {
          if (ReferenceEquals(null, other)) return false;
          if (ReferenceEquals(this, other)) return true;
          return Equals(other.key, key);
      }
      public override bool Equals(object obj)
      {
          if (ReferenceEquals(null, obj)) return false;
          if (ReferenceEquals(this, obj)) return true;
          if (obj.GetType() != typeof (Node&lt;T&gt;)) return false;
          return Equals((Node&lt;T&gt;) obj);
      }
      public override int GetHashCode()
      {
          return (key != null ? key.GetHashCode() : 0);
      }
      public static Node&lt;T&gt; Root()
      {
          return new RootNode&lt;T&gt;();
      }
      public List&lt;Node&lt;T&gt;&gt; getChildren()
      {
          return children;
      }
      [Serializable, DataContract, ProtoContract]
      private class RootNode&lt;T&gt; : Node&lt;T&gt;
      {
          public RootNode() { }
          internal override bool IsParentOf(Node&lt;T&gt; potentialChild)
          {
              return true;
          }
      }
  
  }
  }
  </code></pre>