I have a tree and want to serialize them to xml. The nodes derive from a Nodebase class (found here I think), which fails on serializing.
public class NodeBase : IEqualityComparer, IEnumerable, IEnumerable<NodeBase>
{
public NodeBase Parent { get; private set; }
private readonly IList<NodeBase> children = new ObservableCollection<NodeBase>();
public NodeBase this[int index]
{
get
{
return this.children[index];
}
}
public void AddChild(NodeBase childNode, int index = -1)
{
if (index < -1)
{
throw new ArgumentException("The index can not be lower then -1");
}
if (index > this.Children.Count() - 1)
{
throw new ArgumentException("The index ({0}) can not be higher then index of the last iten. Use the AddChild() method without an index to add at the end".FormatInvariant(index));
}
if (!childNode.IsRoot)
{
throw new ArgumentException("The child node with value [{0}] can not be added because it is not a root node.".FormatInvariant(childNode.ToString()));
}
if (this.Root == childNode)
{
throw new ArgumentException("The child node with value [{0}] is the rootnode of the parent.".FormatInvariant(childNode.ToString()));
}
if (childNode.SelfAndDescendants.Any(n => this == n))
{
throw new ArgumentException("The childnode with value [{0}] can not be added to itself or its descendants.".FormatInvariant(childNode.ToString()));
}
childNode.Parent = this;
if (index == -1)
{
this.children.Add(childNode);
}
else
{
this.children.Insert(index, childNode);
}
}
public void AddChildren(params NodeBase[] childNodes)
{
foreach (var childNode in childNodes)
{
this.AddChild(childNode);
}
}
public bool RemoveChild(NodeBase node)
{
return this.children.Remove(node);
}
public void AddFirstChild(NodeBase childNode)
{
this.AddChild(childNode, 0);
}
public void AddFirstSibling(NodeBase childNode)
{
this.Parent.AddFirstChild(childNode);
}
public void AddLastSibling(NodeBase childNode)
{
this.Parent.AddChild(childNode);
}
public IEnumerable<NodeBase> Leaves
{
get
{
return this.Descendants.Where(n => !n.Children.Any());
}
}
public void AddParent(NodeBase parentNode)
{
if (!this.IsRoot)
{
throw new ArgumentException("This node [{0}] already has a parent".FormatInvariant(this.ToString()), "parentNode");
}
parentNode.AddChild(this);
}
public IEnumerable<NodeBase> Ancestors
{
get
{
if (this.IsRoot)
{
return Enumerable.Empty<NodeBase>();
}
return this.Parent.ToIEnumerable().Concat(this.Parent.Ancestors);
}
}
public IEnumerable<NodeBase> Descendants
{
get
{
return this.SelfAndDescendants.Skip(1);
}
}
public IEnumerable<NodeBase> Children
{
get
{
return this.children;
}
}
public IEnumerable<NodeBase> Siblings
{
get
{
return this.SelfAndSiblings.Where(Other);
}
}
private bool Other(NodeBase node)
{
return !ReferenceEquals(node, this);
}
public IEnumerable<NodeBase> SelfAndChildren
{
get
{
return this.ToIEnumerable().Concat(Children);
}
}
public IEnumerable<NodeBase> SelfAndAncestors
{
get
{
return this.ToIEnumerable().Concat(Ancestors);
}
}
public IEnumerable<NodeBase> SelfAndDescendants
{
get
{
return this.ToIEnumerable().Concat(this.Children.SelectMany(c => c.SelfAndDescendants));
}
}
public IEnumerable<NodeBase> SelfAndSiblings
{
get
{
if (this.IsRoot)
{
return this.ToIEnumerable();
}
return this.Parent.Children;
}
}
public NodeBase GetPreviousSibling()
{
return this.GetPreviousSibling(this);
}
public NodeBase GetPreviousSibling(NodeBase node)
{
if (this.Parent == null)
{
return null;
}
var previousNode = this.Parent.Children.Reverse().SkipWhile(i => !i.Equals(node))
.Skip(1)
.FirstOrDefault();
return previousNode;
}
public NodeBase GetPreviousNode()
{
var previousSibling = this.GetPreviousSibling();
if (previousSibling != null)
{
if (this.HasChildren)
{
NodeBase current = this;
while (true)
{
var child = current.Children.Last();
if (!child.HasChildren)
{
return child;
}
else
{
current = child;
}
}
}
else
{
return previousSibling;
}
}
else
{
if (this.HasParent)
{
return this.Parent;
}
else
{
return null;
}
}
}
public NodeBase GetNextNode()
{
if (this.HasChildren)
{
return this.Children.First();
}
else
{
var nextSibling = this.GetNextSibling();
if (nextSibling != null)
{
return nextSibling;
}
else
{
NodeBase current = this;
NodeBase parent;
while (true)
{
parent = current.Parent;
if (parent == null)
return null;
else
{
var nextSibling2 = parent.GetNextSibling();
if (nextSibling2 != null)
{
return nextSibling2;
}
else
{
current = parent;
}
}
}
}
}
}
public bool HasParent
{
get { return this.Parent != null; }
}
public bool HasChildren
{
get
{
return this.children.Any();
}
}
public NodeBase GetNextSibling()
{
return this.GetNextSibling(this);
}
public NodeBase GetNextSibling(NodeBase node)
{
if (this.Parent == null)
{
return null;
}
var foundNode = this.Parent.Children.SkipWhile(i => !i.Equals(node));
var nextNode = foundNode.Skip(1)
.FirstOrDefault();
return nextNode;
}
public IEnumerable<NodeBase> All
{
get
{
return this.Root.SelfAndDescendants;
}
}
public IEnumerable<NodeBase> SameLevel
{
get
{
return this.SelfAndSameLevel.Where(Other);
}
}
public int Level
{
get
{
return this.Ancestors.Count();
}
}
public IEnumerable<NodeBase> SelfAndSameLevel
{
get
{
return this.GetNodesAtLevel(Level);
}
}
public IEnumerable<NodeBase> GetNodesAtLevel(int level)
{
return this.Root.GetNodesAtLevelInternal(level);
}
private IEnumerable<NodeBase> GetNodesAtLevelInternal(int level)
{
if (level == this.Level)
{
return this.ToIEnumerable();
}
return this.Children.SelectMany(c => c.GetNodesAtLevelInternal(level));
}
public NodeBase Root
{
get
{
return this.SelfAndAncestors.Last();
}
}
public void Disconnect()
{
if (this.IsRoot)
{
throw new InvalidOperationException("The root node [{0}] can not get disconnected from a parent.".FormatInvariant(this.ToString()));
}
this.Parent.children.Remove(this);
this.Parent = null;
}
public bool IsRoot
{
get
{
return this.Parent == null;
}
}
public void Traverse(Action<NodeBase> action)
{
action(this);
foreach (var child in children)
{
child.Traverse(action);
}
}
public IEnumerable<NodeBase> Flatten()
{
return new[] { this }.Union(children.SelectMany(x => x.Flatten()));
}
IEnumerator<NodeBase> IEnumerable<NodeBase>.GetEnumerator()
{
return this.children.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.children.GetEnumerator();
}
public IEnumerator<NodeBase> GetEnumerator()
{
return this.children.GetEnumerator();
}
private static bool IsSameId<TId>(TId id, TId? parentId)
where TId : struct
{
return parentId != null && id.Equals(parentId.Value);
}
#region Equals en ==
public static bool operator ==(NodeBase value1, NodeBase value2)
{
if ((object)(value1) == null && (object)value2 == null)
{
return true;
}
return ReferenceEquals(value1, value2);
}
public static bool operator !=(NodeBase value1, NodeBase value2)
{
return !(value1 == value2);
}
public override bool Equals(Object anderePeriode)
{
var valueThisType = anderePeriode as NodeBase;
return this == valueThisType;
}
public bool Equals(NodeBase value)
{
return this == value;
}
public bool Equals(NodeBase value1, NodeBase value2)
{
return value1 == value2;
}
bool IEqualityComparer.Equals(object value1, object value2)
{
var valueThisType1 = value1 as NodeBase;
var valueThisType2 = value2 as NodeBase;
return Equals(valueThisType1, valueThisType2);
}
public int GetHashCode(object obj)
{
return GetHashCode(obj as NodeBase);
}
public override int GetHashCode()
{
return GetHashCode(this);
}
public int GetHashCode(NodeBase value)
{
return base.GetHashCode();
}
#endregion Equals en ==
}
First the serializer advises that an IEnumerable can only be serialized, when a function Add(System.Object) exists. Why?
I add a dummy function public void Add(object node) { }
and tried to serialize. I get a Stackoverflow exception then. Why, there is nothing special in this class. What I´m doing wrong?
public string SerializeToString<T>(T objectInstance)
{
var xmlSerializer = new XmlSerializer(typeof(T));
var xml = new StringBuilder();
using (TextWriter writer = new StringWriter(xml))
{
xmlSerializer.Serialize(writer, objectInstance);
}
return xml.ToString();
}